【问题标题】:React componentDidMount not updating the stateReact componentDidMount 不更新状态
【发布时间】:2016-03-01 19:47:48
【问题描述】:

我有一个 react 组件,它在构造函数方法中以空白默认状态开始。 当 componentDidMount 我想用我通过 AJAX 从我的 API 获得的东西来更新状态。

这个组件的代码如下:

import React from 'react';
import Header from './Header';
import FeedOwnerColumn from './FeedOwnerColumn';
import FeedColumnRight from './FeedColumnRight';
import ReportBug from './ReportBug';

class FeedApp extends React.Component{
  constructor(){
    super();

    this.addComment = this.addComment.bind(this);
    this.componentDidMount = this.componentDidMount.bind(this);

    this.state = {
      ownerInfo:{},
      ownerDogs:[],
      ownerApps:[],
      ownerChat:{},
      posts:[]
    }
  }
  componentDidMount(e){
    var that = this;
    $.get('/api/getUserInit', function(result) {
      console.log(result);
      this.setState({
        ownerInfo: result.ownerInfo,
        ownerDogs: result.ownerDogs,
        ownerNotifications: result.ownerNotifications,
        ownerChat: result.ownerChat,
        posts: result.posts
      });
    }.bind(this));
  }
  addComment(e){
    e.preventDefault();
    var currTime = new Date();
    currTime = currTime.toLocaleString();  
    var commentContent = e.target.childNodes[0].value; 
    var key = Math.random();
    key = Math.round(key);    
    var newComment = {
      id: key,
      name: "Peter Paprika",
      date: currTime,
      thumb_picture:"/imgs/user-q.jpg",
      profile_link: "/user/123",
      content: commentContent,
      like_amount: 0
    };  
    var postsObj = this.state.posts;
    //console.log(postsObj[0].comments);   
    var newComments = postsObj[0].comments;
    newComments.push(newComment); 
    console.log(newComments);
    this.setState({posts: postsObj}); 
  }
  render() {
    return (
        <div className="clearfix wrapper">
          <Header />
          <FeedOwnerColumn />
          <FeedColumnRight posts={this.state.posts} addComment={this.addComment} />
          <ReportBug />
        </div>
    );
  }
}


export default FeedApp;

不幸的是,componentDidMount 方法中的 this.setState({}) 似乎没有被正确调用,因为没有发生状态更新,而且我的地图函数期望数组无事可做并返回错误。

我想在状态更新中使用的对象如下所示:

ownerChat: Object
ownerDogs: Array[1]
ownerInfo: Object
ownerNotifications: Array[0]
posts: Array[2]

我真的不知道除了这个方法还有什么可以尝试的:/

【问题讨论】:

  • 您的console.log(result) 是否产生任何输出?如果是这样,我怀疑有约束力问题。尝试console.log(this) 看看this 是否指向正确的对象..
  • 我将状态作为道具传递给这个组件:
  • @wintvelt 它产生了我在问题底部显示的对象:)
  • 或者用bind(that)代替this?
  • 按照代码,render() 方法应该被调用两次。它实际上被调用了两次吗?你能在每次调用中console.logthis.state 对象吗?

标签: javascript reactjs ecmascript-6


【解决方案1】:

如果我理解正确,您希望在更新状态时重新呈现安装代码。 ComponentDidMount 只会在组件初始化时触发。所有更新都通过 ComponentDidUpdate 触发。将该接口用于状态更新时将要发生的任何事情。

componentDidUpdate: function (prevProps, prevState) {
...
}

更新

抱歉,我是用手机回答这个问题的,我想我没看错。如果您想在每次状态发生更改时都进行 ajax 调用,您将使用 componentDidUpdate,这不是您所要求的。

我注意到您在构造函数中重新声明了 componentDidMount,它不应该存在,因为它已经声明并且您正在覆盖它。除了那段代码,我在这里看不到任何问题。 componentDidMount 应该触发并正确更新。但是,我读到当对象为空时,您的地图函数会出错。确保您处理的是空状态,因为您的第一个绑定将为空,然后第二个绑定将包含数据。您的映射中的错误可能是这里的罪魁祸首。此示例防止子级被绑定,直到 ajax 调用返回。

import React from 'react';
import Header from './Header';
import FeedOwnerColumn from './FeedOwnerColumn';
import FeedColumnRight from './FeedColumnRight';
import ReportBug from './ReportBug';

class FeedApp extends React.Component{
  constructor(){
    super();

    // only adding functions not defined by super
    this.addComment = this.addComment.bind(this);

    this.state = {
      hasData: false,
      ownerInfo:{},
      ownerDogs:[],
      ownerApps:[],
      ownerChat:{},
      posts:[]
    }
  }
  componentDidMount(e){
    var that = this;
    $.get('/api/getUserInit', function(result) {
      console.log(result);
      console.log('isMounted: ' + this.isMounted());
      if (this.isMounted()) {
        this.setState({
            hasData: true,
            ownerInfo: result.ownerInfo,
            ownerDogs: result.ownerDogs,
            ownerNotifications: result.ownerNotifications,
            ownerChat: result.ownerChat,
            posts: result.posts
        });
      }
    }.bind(this));
  }
  addComment(e){
    e.preventDefault();
    var currTime = new Date();
    currTime = currTime.toLocaleString();  
    var commentContent = e.target.childNodes[0].value; 
    var key = Math.random();
    key = Math.round(key);    
    var newComment = {
      id: key,
      name: "Peter Paprika",
      date: currTime,
      thumb_picture:"/imgs/user-q.jpg",
      profile_link: "/user/123",
      content: commentContent,
      like_amount: 0
    };  
    var postsObj = this.state.posts;
    //console.log(postsObj[0].comments);   
    var newComments = postsObj[0].comments;
    newComments.push(newComment); 
    console.log(newComments);
    this.setState({posts: postsObj}); 
  }
  render() {
    var content = '';
    if (this.state.hasData) {
        content = ( 
          <div>
             <Header />
             <FeedOwnerColumn />
             <FeedColumnRight posts={this.state.posts} addComment={this.addComment} />
             <ReportBug />
          </div>
         );
    }
    return (
        <div className="clearfix wrapper">
            {{ content }}
        </div>
    );
  }
}


export default FeedApp;

让我知道这是否适合你。

【讨论】:

  • 我必须在该函数中初始化组件渲染吗?
  • 感谢您的努力,我发现问题在于映射功能在初始空状态下发生故障,因此停止了 componentWillMount / DidMount 功能
猜你喜欢
  • 1970-01-01
  • 2018-03-22
  • 2017-04-25
  • 2019-01-04
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
相关资源
最近更新 更多