当prop在React中更改时,如何获取数据和setState?

时间:2019-12-27 01:16:58

标签: javascript reactjs

请观看以下代码。我知道如何在组件安装后获取数据并使用数据呈现组件。但是,当属性更改时,组件需要获取其他数据以重新呈现。 以前,我可以使用componentWillReceiveProps()轻松实现此目的,但是现在不建议使用此方法,并且无法在setState()中调用componentDidUpdate()。我不知道如何解决这个问题。

class HotList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      songs: [],
    };
  }

  componentDidMount() {
    this.fetchHotList(this.props.platform);
  }

  // The following method is not recommended for use in current React version.
  // componentWillReceiveProps(nextProps) {
  //   this.fetchHotList(nextProps.platform);
  // }

  // setState() can't be called in componentDidUpdate()
  componentDidUpdate(prevProps) {
    this.fetchHotList(this.props.platform);
  }

  fetchHotList(platform) {
    this.setState({
      loading: true,
    });
    fetch(`/api/hot_list/${platform}`, {
      credentials: 'include',
    }).then(res => res.json())
      .then(json => {
        if (json.status === 'ok') {
          this.setState({
            loading: false,
            songs: json.data.songs,
          });
        }
      })
      .catch(err => console.error(err));
  }

  render() {
    const { songs } = this.state;
    return (
      <div>
        {
          this.state.loading ?
            <Icon type="loading" /> :
            <SongList songs={songs}
            />
        }
      </div>
    );
  }
}

export default HotList;

2 个答案:

答案 0 :(得分:3)

setState中不使用componentDidUpdate不仅仅是硬性规定,更是一种建议。您可以这样做,但是必须小心,否则可能会遇到componentDidUpdate-setState循环。根据{{​​3}}:

  

您可以在componentDidUpdate()中立即调用setState(),但请注意,必须将其包装在如上例中所示的条件下,否则会导致无限循环。

根据上述文档,您可以执行以下操作:

componentDidUpdate(prevProps) {
    if (prevProps.platform != this.props.platform)
        this.fetchHotList(this.props.platform);
  }

答案 1 :(得分:1)

使用componentDidUpdate()时,应检查preProps以避免无限循环

componentDidUpdate(prevProps) {
    if (prevProps.platform !== this.props.platform)
        this.fetchHotList(this.props.platform);
  }

我认为您的this就是完整的回调函数。

好吧,您可以更改一些代码:

fetchHotList(platform) {
    const that = this;
    that.setState({
      loading: true,
    });
    fetch(`/api/hot_list/${platform}`, {
      credentials: 'include',
    }).then(res => res.json())
      .then(json => {
        if (json.status === 'ok') {
          that.setState({
            loading: false,
            songs: json.data.songs,
          });
        }
      })
      .catch(err => console.error(err));
  }