正确更新反应状态/组件?

时间:2019-10-01 08:55:11

标签: javascript reactjs

我正在尝试使我的组件对更新具有反应性。我正在使用componentDidUpdate()检查组件prop状态是否已更改,如果已更改,则需要调用getPosts()函数,如果该prop是,则需要postCount更新改变了。

export default class JsonFeed extends React.Component<IJsonFeedProps, IJsonFeedState> {

  // Props & state needed for the component
  constructor(props) {
    super(props);
    this.state = {
      description: this.props.description,
      posts: [],
      isLoading: true,
      jsonUrl: this.props.jsonUrl,
      postCount: this.props.postCount,
      errors: null,
      error: null
    };
  }

  // This function runs when a prop choice has been updated
  componentDidUpdate() {
    // Typical usage (don't forget to compare props):
    if (this.state !== this.state) {
      this.getPosts();
      // something else ????
    }
  }

  // This function runs when component is first renderd
  public componentDidMount() {
    this.getPosts();
  }

  // Grabs the posts from the json url
  public getPosts() {
    axios
      .get("https://cors-anywhere.herokuapp.com/" + this.props.jsonUrl)
      .then(response =>
        response.data.map(post => ({
          id: `${post.Id}`,
          name: `${post.Name}`,
          summary: `${post.Summary}`,
          url: `${post.AbsoluteUrl}`
        }))
      )
      .then(posts => {
        this.setState({
          posts,
          isLoading: false
        });
      })
    // We can still use the `.catch()` method since axios is promise-based
    .catch(error => this.setState({ error, isLoading: false }));
  }

4 个答案:

答案 0 :(得分:4)

您可以将 componentDidUpdate 更改为:

componentDidUpdate() {
    if (this.state.loading) {
      this.getPosts();
    }
  }

这不会是一个无限循环,因为getPosts()函数会将状态加载设置为false;

现在,每次需要更新时,只需将状态加载设置为true。

如果每次 jsonUrl 更新时都要加载,则需要类似以下内容:

componentDidUpdate(prevProps) {
      if (prevProps.jsonUrl!== this.props.jsonUrl) {
         this.getPosts();
      }
}

我也不明白为什么要通过公开componentDidMount来公开组件状态。

答案 1 :(得分:2)

修改您的getPosts以接收jsonUrl参数,并将以下函数添加到您的类中:

static getDerivedStateFromProps(props, state) {
  if(props.jsonUrl!==state.jsonUrl){
    //pass jsonUrl to getPosts
    this.getPosts(props.jsonUrl);
    return {
      ...state,
      jsonUrl:props.jsonUrl
    }
  }
  return null;
}

您可以摆脱componentDidUpdate函数。

如果您未在构造函数中设置状态jsonUrl,也可以从didmount中删除getPosts。

答案 2 :(得分:1)

 // This function runs when a prop choice has been updated
   componentDidUpdate(prevProps,prevState) {
   // Typical usage (don't forget to compare props):
   if (prevState.jsonUrl !== this.state.jsonUrl) {
     this.getPosts();
     // something else ????
    }
   }

这样,您必须与更新后的状态匹配

答案 3 :(得分:0)

尝试这样做

componentDidUpdate(prevState){
if(prevState.loading!==this.state.loading){
//do Something
    this.getPosts();

}}