设置新状态后状态未更新

时间:2019-08-05 05:48:09

标签: reactjs

我是新来的人,面对问题。我使用Axios从API提取数据,然后必须将该数据设置为状态,并将该值作为道具传递给另一个组件。 我的问题是,在获取API后,我正在使用this.setState更改状态,但是状态没有更改。所以我在下面分享我的代码。

constructor(props){
    super(props);
    this.state={
       employeeData:[]    // setting empty value
    }

}

ComponentDidMount(){
  console.log("Current State"+JSON.stringify(this.state)) ///output = []

  axios.get("http://localhost:8080/hris/api/employee/get/all")  
                                          /// getting values , can see them in network                 
  .then(response => response.data)
  .then((data) => {
    this.setState({ employeeData: data }) ///setting new value
    console.log(this.state.employeeData)   /// can see fetched data 
   })
  .catch(err=> console.log(err))
  console.log("2Nd STATE "+this.state)  /// again empty state, there is no fetched data
}

然后我必须在另一个组件中传递该状态。

render(){
return(
<div className=" col-md-12" style={viewData}>

       <div >
            <p><b>All Employee Details</b></p>         
       </div>

       <Table data={this.state.employeeData}/>
</div>

        )
    }

5 个答案:

答案 0 :(得分:2)

setState是一种异步功能,需要一些时间来设置新的状态值。因此,在此行之后打印新状态将只为您提供以前的状态,而不是新的状态。

您需要callback来检查更改后的状态,

this.setState({ employeeData: data }, () => console.log("2Nd STATE "+this.state))

另一件事是,axios旨在减少.then()的数量。使用axios,您将获得直接的JSON值。您可以删除1个.then()

axios.get("http://localhost:8080/hris/api/employee/get/all") /// getting values , can see them in network                 
  .then(response => {
    this.setState({ employeeData: response.data }, () => console.log("2Nd STATE "+this.state)) // This will give you new state value. Also make sure your data is in `response.data` it might be just `response`.
    console.log(this.state.employeeData)   // This will give you previous state only
   })
  .catch(err=> console.log(err))

答案 1 :(得分:1)

您的render() { return (!this.state.employeeData.length) ? (<div>Loading..</div>) : ( <div className=" col-md-12" style={viewData}> <div > <p><b>All Employee Details</b></p> </div> <Table data={this.state.employeeData} /> </div> ) } 返回的是空值,因为它可能在axios请求完成之前运行。

最初,您的render方法以空状态调用,这可能会引发错误。您需要处理处于加载状态的渲染,直到请求完成为止。

例如,您的渲染可能看起来像这样

$foo = array('a','b','c');
print_r(json_encode($foo));
unset($foo[0]);
echo "\n";
print_r(json_encode($foo));
$foo = array_values($foo);
echo "\n";
print_r(json_encode($foo));

/** Output
["a","b","c"]
{"1":"b","2":"c"}
["b","c"]
*/

答案 2 :(得分:1)

setState是异步的,因此您无法在调用setState()的位置立即看到更改。为了查看更改,您需要执行回调。

this.setState({ employeeData: data },()=>console.log(this.state.employeeData)) ///setting new value

将代码更改为上述格式,更改后即可看到状态更改

答案 3 :(得分:0)

我想这就是您要出问题的地方,尝试一下。它与反应无关。您使用Axios的方式是错误的。

ComponentDidMount(){
  console.log("Current State" + JSON.stringify(this.state));
  axios
    .get("http://localhost:8080/hris/api/employee/get/all")
    .then(response => {
      this.setState({ employeeData: response.data });
    })
    .catch(err => console.log(err));
};

答案 4 :(得分:0)

好的,这两个问题都发生了,因为Axios和this.setState()是异步的。在单个StackOverflow答案中很难解释异步编程,因此我建议检查以下链接:[https://flaviocopes.com/javascript-callbacks/][1]

但是现在要使您的代码正常工作,请将其切换为此

ComponentDidMount() {
  console.log(this.state); // Obviously empty state at beginning

  axios.get("http://localhost:8080/hris/api/employee/get/all")
  .then(res => res.data)
  .then(data => {
    this.setState({employeeData: data}, () => { // Notice the additional function
      console.log(this.state); // You'll see your changes to state
    })
  })
  .catch(err => console.log(err));

  console.log(this.state); // This won't work because Axios is asynchronous, so the state won't change until the callback from axios is fired
}

大多数新的React开发人员不倾向于意识到的部分是this.setState()像axios是异步的,这意味着状态不会立即改变,实际执行的任务会作为后台进程传递。如果您想在状态更改后使用它,则this.setState()函数提供了用于执行此操作的第二个参数

setState(stateChange[, callback])

取自react文档。这里的第二个参数是您可以传递的回调(也称为函数),只有在状态更改发生后才会被触发

// Assuming state = {name: "nothing"}
this.setState({name: "something"}, () => {
  console.log(this.state.name); // logs "something"
});
console.log(this.state.name); //logs "nothing"

希望这会有所帮助!!