在ComponentDidMount上进行异步API调用

时间:2017-08-25 10:36:44

标签: reactjs redux

我有一个ReactJS,期待一个艺术家对象列表。我阅读了ReactJS文档,发现了这个:

reactjs docs

所以我想,好吧,我会在fetchArtists()方法中启动componentDidMoun()动作(我正在使用Redux)。

我这样做,但由于某种原因,它无法正常工作。我要回来的艺术家名单undefined甚至在记录器中想到,我可以看到艺术家被归还。

CODE

这是app容器组件。

class App extends Component {
  componentDidMount() {
    this.props.dispatch(ArtistsListActions.fetchArtists());
  }

  render() {
    return (
      <div className="App">
        <Header />
        <Route exact path="/" render={routeProps => <ArtistList {...routeProps} artists={this.props.artists} />} />
        <Route exact path="/artist/:artistUrlName" component={Artist} />
      </div>
    );
  }
}

ArtistList.propTypes = {
  artists: PropTypes.array.isRequired
};

const mapStateToProps = function(state) {
  console.log('The state is:');
  console.log(state);
}

export default connect(mapStateToProps)(App);

console.log(state);方法中的mapStateToProps()应该会显示加载艺术家的状态,但我不会,artists此时是一个空数组。

console screenshot

更新

我做了你们所有关于在我的mapStateToProps()方法中返回一个选项的建议,但这仍然不起作用。我已经捕捉了this screencast中发生的事情。

3 个答案:

答案 0 :(得分:2)

由于Redux没有得到mapStateToProps方法的预期结果,因此失败,该方法应返回要合并到Component的Object。它被视为开发人员的失败,因此Redux打破了循环并且不再处理事件,迫使开发人员修复它。

还有this.props.dispatch(ArtistsListActions.fetchArtists())的快捷方式,如果您将函数作为第二个参数传递给它,它将自动将其包装在dispatch中并使包装函数在props下可用:

class App extends Component {
  componentDidMount() {
    this.props.fetchArtists();
  }

  render() {
    return (
      <div className="App">
        <Header />
        <Route exact path="/" render={routeProps => <ArtistList {...routeProps} artists={this.props.artists} />} />
        <Route exact path="/artist/:artistUrlName" component={Artist} />
      </div>
    );
  }
}

ArtistList.propTypes = {
  artists: PropTypes.array.isRequired
};

const mapStateToProps = function(state) {
  console.log('The state is:');
  console.log(state);
  const artists = state.artists.artists && state.artists.artists.verified;
  return {artists: artists || []};
}

const mapDispatchToProps = {
  fetchArtists: ArtistsListActions.fetchArtists;
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

答案 1 :(得分:1)

在您的axios呼叫之前抛出错误。初始状态与api的响应形状不匹配。

您可以尝试通过actionCreator对其进行规范化,或者更新您的初始状态以匹配API:

const initialState = {
  isFetching: false,
  fetchComplete: false,
  artists: {artists: {verified:[]}},
  error: null
};

为了完整性,这是你改变初始状态时需要的mapStateToProps:

const mapStateToProps = function(state) {
    console.log(state);
  return {
        artists: state.artists.artists.verified
    }
}

答案 2 :(得分:0)

所以,你可能忘了派遣道具......

class App extends Component {
  componentDidMount() {
    this.props.fetch(); //Call just your mapped dispatch
  }

  render() {
    return (
      <div className="App">
        <Header />
        <Route exact path="/" render={routeProps => <ArtistList {...routeProps}     artists={this.props.artists} />} />
        <Route exact path="/artist/:artistUrlName" component={Artist} />
      </div>
    );
  }
}

ArtistList.propTypes = {
  artists: PropTypes.array.isRequired
};

const mapStateToProps = function(state) {
  console.log('The state is:');
  console.log(state);
}

const mapDispatchToProps = (dispatch) => {
    return {
        fetch: () => dispatch(ArtistsListActions.fetchArtists())
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(App); //Pass new method here