简体   繁体   English

this.setState使变量未定义?

[英]this.setState makes variable undefined?

I'm trying to increment my state variable, but whenever I do so an error pops up which says that the variable state is undefined. 我正在尝试增加我的状态变量,但每当我这样做时会弹出一个错误,表示变量状态是未定义的。 I defined my variable inside the constructor . 我在构造函数中定义了我的变量 Obviously something is going on in the setState function. 显然,setState函数正在发生一些事情。

Here is the code which renders an error: 以下是呈现错误的代码:

displayDiv(){
  var arr=[];
  if (this.state.flag[2]){
    this.setState({counter:counter+4}); // error:undefined
    for (let i = this.state.counter-4; i < this.state.counter; i++)
      arr.push(this.state.arrayHeader[0].content);
    }
  }
 return(
   arr.map(function(item,i){
     return (
       <div className="bodydiv col-sm-3">
         <Header/>
         <Content/>
         <Tags/>
       </div>
     );

    })
  );
}

Here is the defined variable inside the constructor: 这是构造函数中定义的变量:

constructor(props){
  super(props);

  this.state = {
    arrayHeader:[],
    arraytag1:[],
    arraytag2:[],
    counter:0,
    flag:[false,false,false]
  }
}

Your counter +4 points nowhere. 你的counter +4点无处可寻。

It should be this.state.counter + 4 它应该是this.state.counter + 4

Also, if you are calling this function on the render() make sure it has been previously binded, you can do that like this on the constructor: 此外,如果您在render()上调用此函数,请确保它先前已绑定,您可以在构造函数上执行以下操作:

this.displayDiv = this.displayDiv.bind(this);

I think its simple, try this in function displayDiv 我认为它很简单,在功能displayDiv尝试这个

this.setState({counter: this.state.counter+4});

you forgot the this.state at this line :) 你在这一行忘记了this.state :)

To add to the other good answers: 要添加其他好的答案:

In short, you probably want something like this to be safe: 简而言之,您可能希望这样的东西是安全的:

this.setState((prevState) => ({
    ...prevState, counter: prevState.counter+4
}));

Yes, your current problem was due to the undefined local variable counter in this statement: 是的,您当前的问题是由于此语句中未定义的局部变量counter

this.setState({ counter: counter+4 });

A simple solution (as pointed out by other answers already) is to refer to the respective state variable: 一个简单的解决方案(正如其他答案所指出的那样)是指各自的状态变量:

this.setState({ counter: this.state.counter+4});

As pointed out by cdaiga , you'd probably want to preserve the other properties on your state since setState() is replacing the current state with the parameter provided to it and you'd effectively loose all other values on it. 正如cdaiga所指出的,你可能想要保留你状态中的其他属性,因为setState()正在用提供给它的参数替换当前状态,你实际上会松开它上面的所有其他值。 You could do it like this: 你可以这样做:

this.setState({ ...this.state, counter: this.state.counter+4 });

As per the React Documentation , you should also take the asynchronous nature of setState() into account. 根据React Documentation ,您还应该考虑setState()的异步特性。

React may batch multiple setState() calls into a single update for performance. React可以将多个setState()调用批处理为单个更新以提高性能。

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. 因为this.propsthis.state可以异步更新,所以不应该依赖它们的值来计算下一个状态。

For example, this code may fail to update the counter: 例如,此代码可能无法更新计数器:

 // Wrong this.setState({ counter: this.state.counter + this.props.increment, }); 

To fix it, use a second form of setState() that accepts a function rather than an object. 要修复它,请使用第二种形式的setState()接受函数而不是对象。 That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument: 该函数将接收先前的状态作为第一个参数,并将更新作为第二个参数应用于道具:

 // Correct this.setState((prevState, props) => ({ counter: prevState.counter + props.increment })); 

We used an arrow function above, but it also works with regular functions 我们使用了上面的箭头函数,但它也适用于常规函数


In your specific example, we would end up with something like this (as already stated at the top): 在您的具体示例中,我们最终会得到类似的结果(如上所述):

this.setState((prevState) => ({
    ...prevState, counter: prevState.counter+4
}));

Additional side note: due to this asynchronous nature of this.setState() , accessing this.state after calling this.setState() will still return its old value. 附加说明:由于this.setState()这种异步性质,在调用this.setState()之后访问this.state仍将返回其旧值。 Your original posted code is accessing this.state.counter immediately afterwards: 您原来发布的代码后来立即访问this.state.counter

this.setState({counter:counter+4}); // error:undefined
for (let i = this.state.counter-4; i < this.state.counter; i++)
    arr.push(this.state.arrayHeader[0].content);
}

Fortunately in this case you're not using the variable i inside the loop and the this.state.arrayheader[0].content is not being updated, ie the following would be equivalent: 幸运的是,在这种情况下,你没有在循环中使用变量i而且this.state.arrayheader[0].content没有被更新,即以下内容是等效的:

this.setState((prevState) => ({
    ...prevState, counter: prevState.counter+4
}));
for (let i = 0; i < 4; i++) {
     arr.push(this.state.arrayHeader[0].content);
}

You can replace: 你可以替换:

this.setState({counter:counter+4}); // error:undefined

with: 有:

const { counter } = this.state; // getting the counter from state
this.setState({counter:counter+4});

But then hope you really want to flush out all the other attributes of the state. 但是,希望你真的想要清除状态的所有其他属性。 Else you should do: 否则你应该这样做:

const { counter } = this.state;
this.setState(Object.assign({},this.state,{counter: counter + 4})); 

See how to use Object.assign() method 了解如何使用Object.assign()方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM