【问题标题】:Rendering part of a React function component after async call gets completed在异步调用完成后渲染 React 函数组件的一部分
【发布时间】:2019-10-18 10:27:59
【问题描述】:

我正在使用带有 React 功能组件的 material-ui 并使用它的 Autocomplete 组件。我自定义了它,每当我更改输入字段中的文本时,我希望该组件呈现新的搜索结果。

callAPI("xyz")

我在action中调用API,使用xyz参数,从这个函数组件调用dispatch方法。

这里的问题是,当组件进行调用时,它应该等待API响应然后渲染结果,但是它得到了一个未解析的promise,所以它渲染失败。

<Paper square>
    {callAPI("xyz").results.map(
        result => console.log(result);
    )}
</Paper>

由于结果是一个未解决的承诺,它不会映射。 我需要一些方法来仅在数据可用时调用地图,或者在数据存在之前显示一些文本,然后在获取数据后更改。

任何更正此代码的建议都会非常有帮助。

编辑:

function IntegrationDownshift() {
    return (
        <div>
            <Downshift id="downshift-simple">
                {({
                    getInputProps,
                    getItemProps,
                    getMenuProps,
                    highlightedIndex,
                    inputValue,
                    isOpen,
                    selectedItem
                }) => (
                    <div>
                        {renderInput({
                            fullWidth: true,
                            InputProps: getInputProps({
                                placeholder: "Search users with id"
                            })
                        })}

                        <div {...getMenuProps()}>
                            {isOpen ?
                                 <Paper square>
                                {callAPI(inputValue).users.map(
                                    (suggestion, index) =>
                                        renderSuggestion({
                                            suggestion,
                                            index,
                                            itemProps: getItemProps({
                                                item:
                                                    suggestion.userName
                                            }),
                                            highlightedIndex,
                                            selectedItem
                                        })
                                )}
                            </Paper>  
                             : null}
                        </div>
                    </div>
                )}
            </Downshift>
        </div>
    );
}

【问题讨论】:

  • 调度触发加载器的动作或数据正在加载的一些文本,一旦解决,调度加载器转动和设置数据的动作。在您的 jsx 中,您可以编写一个三元检查 loader 是否为 true 渲染加载器组件,否则渲染数据
  • @DILEEPTHOMAS 您能否为您的示例提供任何伪代码或示例
  • 你能提供更多的代码吗,我认为paper是一个定制的组件。因此,在更改时,您将调用一个道具,并且调度在父组件中完成
  • @DILEEPTHOMAS 添加了附加代码以供参考,您可以看到 callAPI 方法采用 inputValue 并返回与用户的 Object。我想在上面应用地图并调用另一个渲染。但是,当它最初加载时, 会在没有数据的情况下呈现,因为 promise 仍未解决,它会因 map 而失败。

标签: javascript reactjs material-ui react-component react-async


【解决方案1】:

React 16.8 引入Hooks

Hooks 是让你“挂钩”到 React 状态和生命周期的函数 功能组件的特征。

所以你有useState(),你可以用一个空数组声明一个状态变量,并在useEffect() 中调用你的API,以便在你从API 获得响应时填充状态:

function App() {

  const [data, setData] = useState([]);

  useEffect(() => {
    callAPI("xyz").then(result => {
      setData(result);
    })  
  }, []);

  if(!data.length) return (<span>loading...</span>);

  return (
    <Paper square>
        {data.map(
            result => console.log(result);
        )}
    </Paper>
  );
}

更多关于钩子的信息:https://reactjs.org/docs/hooks-intro.html

【讨论】:

  • 感谢您介绍钩子,这可能会有所帮助
【解决方案2】:

处理这个问题的最简单方法是使用三元表达式 最好的做法是在生命周期方法中调用您的 API 请求,然后将结果保存在本地状态中。

componentDidMount() {
    callAPI("xyz").results.map(
        result => this.setState(result);

}

<Paper square>
    {this.state.results ?
      this.state.results.map(
        result => console.log(result);
      : <p> Loading... </p>
    )}
</Paper>

【讨论】:

  • 但是正如我所说的它是一个无状态的功能组件,所以我不能使用生命周期方法和localstate
  • 你在这里发出一个API请求,你为什么不把它变成一个有状态的组件?
  • 虽然无状态组件是用于渲染目的,但据我所知,如果它进行 API 校准,它没有必要是有状态的,除非它通过存储 API 数据来维护状态以供进一步使用参考。如果我错了,我准备纠正。谢谢
猜你喜欢
  • 2018-06-27
  • 1970-01-01
  • 2018-09-30
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多