简体   繁体   English

如何将 useMemo 与外部 API 一起使用?

[英]How to use useMemo with an external API?

I'm working with react-table library for filtering and pagination.我正在使用react-table库进行过滤和分页。 I am requesting data from a custom API using Node and rendering it using useTable hook from react-table .我正在使用Node从自定义 API 请求数据,并使用react-table中的useTable钩子呈现它。 The documentation for react-table says the table data should be memoized, so I use the useMemo hook. react-table的文档说应该记住表数据,所以我使用了useMemo钩子。 The code is as shown:代码如图所示:

  const data = React.useMemo(() => {
    axios.get("/custom/api/endpoint")
      .then((res) => {
        return res.data;   //Returns an array of objects
      })
      .catch((err) => {
        console.log("err");
      });
  }, []);

However, I am getting the following error:但是,我收到以下错误:

Uncaught TypeError: Cannot read property 'forEach' of undefined
    at accessRowsForColumn (useTable.js:591)
    at useTable.js:195
    .
    .

Can anyone help me figure this?谁能帮我解决这个问题? Thanks in advance!提前致谢!

You are memoizing the promise that axios creates.您正在记忆 axios 创建的 promise。 Instead make the call with useEffect() , and set the state.而是使用useEffect()进行调用,并设置 state。 Unless you'll set the state again, the data would not change:除非您再次设置 state,否则数据不会更改:

const [data, setData] = useState([]); // use an empty array as initial value

useEffect(() => {
  axios.get("/custom/api/endpoint")
    .then((res) => {
      setData(res.data); // set the state
    })
    .catch((err) => {
      console.log("err");
    });
}, []);

You're using this arrow function inside the useMemo call.您在useMemo调用中使用此箭头 function 。

() => {
    axios.get("/custom/api/endpoint")
      .then((res) => {
        return res.data;   //Returns an array of objects
      })
      .catch((err) => {
        console.log("err");
      });
  }

And it returns undefined .它返回undefined It's because axios.get returns a Promise and you're not assigning it to anything and your arrow function implicitly returns undefined as it doesn't have an explicit return statement.这是因为axios.get返回一个Promise并且您没有将其分配给任何东西,而您的箭头 function 隐式返回undefined的返回语句,因为它没有显式return语句。

Try this:尝试这个:

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

useEffect(() => {
  axios.get("/custom/api/endpoint")
    .then((res) => {
      setData(res.data);
    })
    .catch((err) => {
      console.log("err");
    });
}, []);

Here useEffect is called after the initial render of the component, which calls axios.get .这里useEffect在组件的初始渲染之后调用,它调用axios.get It is an async function so the useEffect call immediately returns after calling it.它是一个异步 function 因此useEffect调用在调用后立即返回。 When the axios.get async call succeeds it calls the arrow function within the then call which assigns the data from the response to the data state variable.axios.get异步调用成功时,它会在then调用中调用箭头 function,将响应中的数据分配给data state 变量。

You have defined a promise and not returning it, so the code is not waiting for the promise to resolve.您已经定义了 promise 并且没有返回它,因此代码不会等待 promise 解决。 Try with async await syntax, which is easier to visualize the flow.尝试使用 async await 语法,这更容易可视化流程。

  const data = React.useMemo(async () => {
    
      try {
        const res = await axios.get("/custom/api/endpoint") 
        return res.data
      } catch(err) {
        throw err
      }
 
  }, []);

These solutions not succesful need for me, because I structured my pattern for project.这些解决方案对我来说并不成功,因为我为项目构建了我的模式。 My data request with redux dispatch (so redux-thunk) actually I used redux-toolkit for fast development.我使用 redux 调度(所以 redux-thunk)的数据请求实际上我使用 redux-toolkit 进行快速开发。

I solved like this;我是这样解决的;

function Table ({ columns, data }) {
    // ...
    return /* standart react-table basic component */
}

function MyTable(props) {
  const columns = useMemo(() => props.columns, [props.columns]);
  const data = useMemo(() => props.data, [props.data]);

  return <Table columns={columns} data={data} />;
}

const PageListTable = () => {
    // ...
    const columns = [...]; // static variable

    useEffect(
      async () => {
        const payload = {};

        // some codes

        dispatch(getAllData(payload));
      },
      [activeId, isAuth] // listen from with useSelector
    );

    // some codes..

    return (
        {/* ..... */}

        <HOC.Async status={loading}>
            <MyTable
                columns={columns}
                data={getAllDataState.data}
            />
        </HOC.Async>

        {/* ..... */}
    );
}

My package.json specs like this;我的 package.json 规格是这样的;

"react": "^17.0.2",
"react-redux": "^7.2.4",
"react-table": "^7.7.0",
"@reduxjs/toolkit": "^1.6.1",

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM