【问题标题】:React setState() after fetch not rerendering在获取不重新渲染后反应 setState()
【发布时间】:2019-02-21 10:10:14
【问题描述】:

我正在 componentDidMount()获取数据(我正在以我想要的形式获取它们) 我想将它们保存在组件状态this.setState。 状态没有改变。

  • 我的控制台日志显示我正在调用 setState - 有条件
  • 我试过const that = this

组件没有重新渲染,状态也没有改变,我想知道为什么。

我的代码:

export class Offers extends Component {
    constructor(props) {
        super(props);
        this.renderOffer = this.renderOffer.bind(this);
        this.state = {
        ...
        };
    }
    componentWillMount() {
        this.setState(() => ({
            offer: {},
            isLoading: true,
            isMyOffer: false,

            ...
        }));
    }

    componentDidMount() {
        console.log('MOUNTED');
        const { profile } = this.props;
        if (profile) {
            this.setState(() => ({
                isLoading: false
            }));
        }
        if (profile && profile._id) {
            this.setState(() => ({
                isMyOffer: true,
                ...
            }));

            fetch(`/api/offers-by/${profile._id}`,{
                method: 'GET'
            })
           .then(response => response.json())
           .then(offers => {
               if(!offers || !offers.length) {
                   this.setState(() => ({
                   isLoading: false
                  })
                  );
              } else {
                  console.log('ELSE', offers[0]._id); // getting proper data
                  console.log('THIS', this) // getting this object 
                  const offerData = offers[0]
                  this.setState(() => ({
                      offer: offerData,
                      isLoading: false
                  })) //  then
              }}) // fetch
              console.log('STATE', this.state)
          }
          console.log('STATE', this.state)
    }

【问题讨论】:

  • 您是否尝试过调用setState 传递对象而不是函数?
  • 我没有,根据反应源代码,应该没关系。
  • 你怎么知道状态没有变化?如果您的调试尝试是通过console.log(this.state) 进行的,那么您的调试是错误的。 fetch 是异步的,所以状态还没有改变(它会在 fetch 完成并执行 then 之后*)。但即使您再次在then 方法中记录状态,它也不会起作用,因为setState 也是异步的。使用setState 回调记录并查看状态是否改变。
  • 我也在使用控制台登录渲染,所以我看到那里的状态没有改变。我的错误没有在问题中包含此信息。
  • @AgataAndrzejewska 您发布的代码不应出现您描述的问题(如果到达ELSETHIS 日志)。您确定您的代码中没有其他部分可能会干扰状态设置吗?任何控制台错误/警告?您能否发布整个组件代码(也许还有它的实时版本?

标签: javascript reactjs fetch setstate


【解决方案1】:

setState 有一个回调方法作为第二个参数。你应该在初始 setState 之后使用它。这是有效的,因为 setState 本身是一个异步操作。setState() 方法不会立即更新组件的状态,而是如果有是多个 setState,它们将被批处理到一个 setState 调用中。

this.setState(() => ({
            isLoading: false
        }),() =>{
   /// You can call setState again here and again use callback and  call fetch and invoke setState again..
});

理想情况下,您可以将一些 setState 重构为单个 setState 调用。从一个空对象开始,然后根据条件向您的对象添加属性。

const updatedState ={}
if(loading){
 updatedState.loading = false
}
if(profile &&..){
 updatedState.someProperty = value.
}

this.setState(updatedObject,()=> {//code for fetch..
}) // Using the object form since you don't seem to be in need of previous State.

【讨论】:

  • 感谢您的回复!您的建议帮助我找到了解决方案。
  • 酷,很高兴为您提供帮助
猜你喜欢
  • 2019-12-13
  • 2020-05-06
  • 2018-07-17
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 2016-09-09
相关资源
最近更新 更多