未捕获(承诺)TypeError:this.setState不是函数

时间:2019-09-03 15:06:50

标签: reactjs async-await react-router state

在我的父组件中,我正在从json文件加载数据并使用它来设置状态。然后使用react-router,将状态传递给子组件,该子组件将数据呈现在路由中。此行为按预期方式工作。但是,当我尝试刷新路由时,父组件的状态(以及子组件的props)会丢失,并且页面会引发未定义的错误。

我试图在子组件的ComponentDidMount生命周期方法中从父组件调用数据加载功能,但是应用程序抛出错误Uncaught (in promise) TypeError: this.setState is not a function

父组件代码:

async loadWorldData() {
 await axios.get("../factbook.json")
    .then(res => {
      let Data = res && res.data.countries;
      Data = Object.values(Data).map(country => country.data) || [];
      let newData = this.removeNull(Object.values(Data));

      this.setState({ worldData: newData})
    });
}

子组件代码:

componentWillMount = () => {
  this.props.loadWorldData();
}

我不知道另一种在子项的生命周期方法中不调用父函数的情况下重新加载应用程序状态的方法。

2 个答案:

答案 0 :(得分:0)

尝试以下操作:这可能是一个有约束力的问题。

 loadWorldData = async() => {

 const res = await axios.get("../factbook.json")
 let data = res && res.data.countries;
 data = Object.values(Data).map(country => country.data) || [];
 let newData = this.removeNull(Object.values(Data));
 this.setState({ worldData: newData });

}

为什么这不起作用?

要使用setState,您必须有权访问this。普通功能未绑定到this。有两种方法可以解决此问题:

首先:将函数绑定到构造函数中。

class App extends React.Component {
   constructor(props) {
      super(props);
      this.loadWorldData = this.loadWorldData.bind(this);
   }
}

第二个:粗箭头功能:

由于胖箭头函数已绑定到this,因此您不必担心将它们绑定在constructor内部,如第一个示例所示。

答案 1 :(得分:0)

          async loadWorldData() {
           const self = this;
           await axios.get("../factbook.json")
            .then(res => {
               let Data = res && res.data.countries;
                 Data = Object.values(Data).map(country => country.data) || 
                                 [];
                  let newData = this.removeNull(Object.values(Data));

                  self.setState({ worldData: newData})
                 });
           }

您可以删除不需要的异步消息。