【问题标题】:How to update React component when async prop promise resolves?异步 prop 承诺解决时如何更新 React 组件?
【发布时间】:2019-07-22 23:28:23
【问题描述】:

假设我有一个渲染PivotGrid 组件的组件。这个PivotGrid 需要一些数据,一个对象数组。

function My_component(props) {
    return <PivotGrid dataSource={props.data} />
}

但是,我要传入的 data 属性是异步函数的结果。

const get_data = async () => {
    return await o(url, options).get('foo').query({})
}

ReactDOM.render(<My_component data={get_data()}/>, document.getElementById('root'));

发生的情况是组件在来自get_data() 的承诺被解析之前呈现,并且 PivotGrid 没有数据。

我希望组件在 promise 解决并实际返回数据时重新渲染。我已经尝试过 React 的 useState() 的变体,将 props.data 视为状态变量,这样当承诺返回时,状态会改变,组件也会更新。但这还没有奏效。

const [gridData, setGridData] = useState(props.data);
props.data.then((r) => {
    setGridData(props.data)
})

上述尝试都失败了。实现此功能的最佳方式是什么,当prop.data 解析并实际保存我想要的数据时,组件会重新呈现?

【问题讨论】:

  • 您可以在 My_component 中调用 get_data 函数,而不是通过 props 传递数据,在那里您可以使用钩子或将其转换为 React 组件来控制组件的呈现。
  • 感谢@SimoMatavulj 的回复。我想将此数据作为道具传递,以便此组件可重用。
  • 您可以创建一个包装器来获取数据并将其传递给您的My_component

标签: javascript reactjs asynchronous properties async-await


【解决方案1】:

为 My_component 使用钩子和容器组件应该可以工作。

我的组件容器.js:

import React, {useState, useEffect} from 'react'
import My_component from './my-component'

export default () => {
   const [data, setData] = useState(null)
   useEffect(async () => {
     const fetchData = async () => {
         const result = await o(url, options).get('foo').query({})

         setData(result);
     };

    fetchData();
   }, [])

   return <My_component dataSource={data} />
}

在你的入口点:

import My_component_container from './my-component-container'

ReactDOM.render(<My_component_container />, document.getElementById('root'))

【讨论】:

  • 感谢您的回复!我已经尝试过了,但效果并不好,但我认为这是朝着正确方向迈出的一步。以这种方式创建容器组件会引发错误,说 useEffect 无法返回 async 函数,而正确的方法是在 useEffect 中编写一个 async 函数并立即调用它。但是,这仍然不起作用...
  • @jpc 你是对的,我更新了你的评论的答案
【解决方案2】:

为什么不改成下面这样的有状态组件

class My_component extends React.Component {
   state = {};

   componentDidMount(){
     this.get_data()
   }

   get_data = async () => {
     const data = await o(url, options).get('foo').query({});
     this.setState({ data });
   }

   render() {
      const { data } = this.state;
      return <PivotGrid dataSource={data} />
   }

}

【讨论】:

  • 由于这个项目的性质,它必须是一个功能组件。我还必须将数据作为道具传递,因为这个组件必须是可重用的,并且会从不同的来源获取数据。
猜你喜欢
  • 2015-12-08
  • 2021-11-26
  • 2020-11-21
  • 2019-04-13
  • 1970-01-01
  • 2020-07-04
  • 2019-03-19
  • 1970-01-01
  • 2021-01-02
相关资源
最近更新 更多