Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 更新状态-为什么在调用setState时创建状态的新副本?_Reactjs_Immutability - Fatal编程技术网

Reactjs 更新状态-为什么在调用setState时创建状态的新副本?

Reactjs 更新状态-为什么在调用setState时创建状态的新副本?,reactjs,immutability,Reactjs,Immutability,反应文档: 切勿直接改变此.state,因为之后调用setState() 可能会取代你的变异。将此状态视为 不变的 这很清楚 class App extends React.Component { state = { data: [] } 以下是我的理解 updateState(event) { const {name, value} = event.target; let user = this.state.user; // this is a referen

反应文档:

切勿直接改变此.state,因为之后调用
setState()
可能会取代你的变异。将
此状态视为
不变的

这很清楚

class App extends React.Component {
  state = {
   data: []
  } 
以下是我的理解

  updateState(event) {
   const {name, value} = event.target;
   let user = this.state.user; // this is a reference, not a copy...
   user[name] = value; // 
   return this.setState({user}); // so this could replace the previous mutation
  }
  updateState(event) {
  const {name, value} = event.target;
  let user = {...this.state.user, [name]: value};
  this.setState({user});
  }
下面这个我不明白

  updateState(event) {
   const {name, value} = event.target;
   let user = this.state.user; // this is a reference, not a copy...
   user[name] = value; // 
   return this.setState({user}); // so this could replace the previous mutation
  }
  updateState(event) {
  const {name, value} = event.target;
  let user = {...this.state.user, [name]: value};
  this.setState({user});
  }
我理解(如前一示例中所述),我不应仅:

  • 不调用setState直接改变状态;或
  • 对其进行变异,然后使用setState 但是,为什么我不能(没有直接变异)调用setState而不创建状态的新副本(无扩展运算符/
    Object.assign
    )?以下情况会有什么问题:

      getData = () => {
       axios.get("example.com") ...
        this.setState({
         data:response.data
        })
      } 
    
    为什么应该是:

      getData = () => {
       axios.get("example.com") ...
        this.setState({
         data:[...data, response.data]
        })
      } 
    
     render (){ 
      ...
     }  
    }
    
    以下情况会有什么问题:

      getData = () => {
       axios.get("example.com") ...
        this.setState({
         data:response.data
        })
      } 
    
    绝对没有,除非您不想将
    this.state.data
    的内容替换为
    response.data

    为什么应该是:

      getData = () => {
       axios.get("example.com") ...
        this.setState({
         data:[...data, response.data]
        })
      } 
    
     render (){ 
      ...
     }  
    }
    
    因为使用spread,您不会丢失
    this.state.data
    的内容-您基本上是将新的响应推送到
    data
    数组中

    注意:您应该在
    设置状态
    中使用callback,从
    此状态
    访问当前的
    数据

    this.setState((prevState) => ({
       data: [...prevState.data, response.data],
    }));
    

    因为在您的示例中,您希望将响应数据添加到数组的末尾,而不是用它替换数组?它们根本不是等价的,这与变异问题是分开的。你这样做是因为你只需要处理新的数据实例。这些新实例是基于前一个实例和新数据创建的。啊,好的,我现在知道了。创建状态副本仅适用于我希望向数组或对象添加而不是替换某些内容的情况。谢谢@javascripting:请记住,如果函数与React中的状态相关,则要避免变异函数。当直接在状态下操作时,您不想使用例如
    push
    splice
    。您必须使用其他一些不会变异并返回新实例的函数,如
    slice
    concat
    或spread syntax.@javascripting或基本上先创建一个深度副本,然后才能在该副本上使用变异函数,而不会直接变异状态。另外,我还有一个问题。使用spead运算符/Object.assign或concat等仅在其不是更深嵌套状态时有效。例如:var state={u2ndlevel:{arr:[]}}-->在本例中,嵌套对象仍将被引用,因此我最终将直接修改state。在这里做什么好(不使用任何不变性库帮助程序)?谢谢@javascripting在深度状态下,您只需更深入;)分解整个状态,直到达到指定的部分。不管怎么说,是的,最好是尽可能保持州内的平坦。