反应严格模式

Pro*_*r67 2 javascript reactjs react-strictmode

我正在处理我的项目,我注意到当打开严格模式时,它会将两个相同的元素推入我的数组中。当严格模式关闭时,它仅将一个元素推入数组。有什么解释为什么会发生这种情况吗?

import {getRandomNumber} from './utils';


export function registerTicket() {
    const newTicket = {
        number: getRandomNumber(),
        color: 'red',
    }
    this.setState((prevState) => {
        prevState.tickets.push(newTicket);
        return {
            remainingTickets: --prevState.remainingTickets,
            tickets: prevState.tickets,

        }
    })
}
Run Code Online (Sandbox Code Playgroud)

这是我的状态。

    this.state = {
      winningNumber: getRandomNumber(),
      remainingTickets: 5,
      tickets: [],
      finished: false
    };
Run Code Online (Sandbox Code Playgroud)

Dre*_*ese 5

ReactStrictMode通过有意地重复调用某些生命周期方法和 React 钩子来帮助暴露无意的副作用。updatersetState函数被调用两次。我将留下对链接问题的深入解释。

检测意外的副作用

tickets当您将新元素推入其中以及预先递减状态时,您无意的副作用是前一个状态的状态突变remainingTickets。帽子戏法是您也不会返回新的tickets数组引用。

this.setState((prevState) => {
  prevState.tickets.push(newTicket); // <-- mutation!!
  return {
    remainingTickets: --prevState.remainingTickets, // <-- mutation!!
    tickets: prevState.tickets, // <-- same old array reference
  }
})
Run Code Online (Sandbox Code Playgroud)

解决方案是将先前的状态数组浅复制到新的数组引用中并附加新元素。

this.setState((prevState) => ({
  remainingTickets: prevState.remainingTickets - 1,
  tickets: [...prevState.tickets, newTicket],
}));
Run Code Online (Sandbox Code Playgroud)