【问题标题】:With a React Hooks' setter, how can I set data before the component renders?使用 React Hooks 的 setter,如何在组件呈现之前设置数据?
【发布时间】:2019-11-19 13:12:22
【问题描述】:

我将一个名为 Products 的 JS 对象导出到此文件,只是为了在构建/测试时替换一个真正的 API 调用。我想将函数的状态设置为对象,但已映射。我的组件看起来像这样:

function App() {
  const [rooms, setRooms] = useState([]);
  const [days, setDays] = useState([]);
  const roomsMapped = products.data.map(room => ({
    id: room.id,
    title: room.title
  }))

  useEffect(() => {
    setRooms(roomsMapped);
  })

  return ( etc )

这将返回以下错误:Error: Maximum update depth exceeded

我觉得我在这里遗漏了一些非常明显的东西,但对 React 和 Hooks 来说还是很陌生。如何在组件渲染之前设置这些数据?

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    只需将其声明为rooms的初始值

     const Component = () =>{
         const [rooms, setRooms] = useState(products.data.map(room => ({
             id: room.id,
             title: room.title
          })))
     }
    

    您也可以使用lazy initial state 来避免在每次渲染时重新处理初始值

     const Component = () =>{
         const [rooms, setRooms] = useState(() => products.data.map(room => ({
             id: room.id,
             title: room.title
          })))
     }
    

    【讨论】:

      【解决方案2】:

      useEffect改成这个

      useEffect(() => {
          setRooms(roomsMapped);
        },[])
      

      【讨论】:

        【解决方案3】:

        Lazy initialisation为参数,函数为useState

        import React, { useState } from "react";
        
        function App() {
          const [rooms, setRooms] = useState(() => {
            // May be a long computation initialization
            const data = products.data || [];
            return data.map(({ id, title }) => ({ id, title }));
          });
        
          return (
            // JSX stuffs
          )
        }
        

        【讨论】:

          【解决方案4】:

          你可以使用 this.set 初始值的默认道具和空列表。

          【讨论】:

            【解决方案5】:

            您收到“错误:超出最大更新深度”,因为您的 useEffect 函数没有依赖数组。解决此问题的最佳方法是将空数组作为第二个参数传递给 useEffect,如下所示:

            useEffect(() => {
                setRooms(roomsMapped);
              },[]) <= pass empty array here 
            

            这将阻止组件重新渲染,如果您希望组件在道具更改时重新渲染,您可以像这样传递数组中的道具:

            useEffect(() => {
                setRooms(roomsMapped);
              },[props.props1,props.props2])
            

            在这里,您可以传递任意数量的道具...

            【讨论】:

              猜你喜欢
              • 2017-06-11
              • 1970-01-01
              • 2020-01-29
              • 2021-05-19
              • 2021-10-31
              • 1970-01-01
              • 2021-07-09
              • 2021-06-02
              • 1970-01-01
              相关资源
              最近更新 更多