代码之家  ›  专栏  ›  技术社区  ›  enzeberg

当属性在React中改变时,如何获取数据并设置状态?

  •  0
  • enzeberg  · 技术社区  · 5 年前

    请注意以下代码。我知道如何获取数据,并在安装组件后用数据呈现组件。但是组件需要获取其他数据,以便在道具更改时重新呈现。 以前,我可以用 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 回复  |  直到 5 年前
        1
  •  3
  •   Ismael Padilla    5 年前

    不使用 setState 在里面 componentDidUpdate 与其说是硬性规定,不如说是建议。可以这样做,但必须小心,否则可能会进入componentDidUpdate setState循环。根据 the docs :

    您可以在componentDidUpdate()中立即调用setState(),但请注意,它必须包装在与上面示例类似的条件中,否则将导致无限循环。

    根据上面的文档,您可以这样做:

    componentDidUpdate(prevProps) {
        if (prevProps.platform != this.props.platform)
            this.fetchHotList(this.props.platform);
      }
    
        2
  •  1
  •   Ryan Nghiem    5 年前

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

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

    我想也许你的 this 这是fecth回调函数。

    好吧,你可以更改一点代码:

    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));
      }