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

How to use useMemo with an external API?

我正在使用 react-table 库进行过滤和分页。我正在使用 Node 从自定义 API 请求数据,并使用来自 react-tableuseTable 钩子呈现它。 react-table 的文档说 table 数据应该被记忆,所以我使用 useMemo 挂钩。代码如图:

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

但是,我收到以下错误:

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

谁能帮我解决这个问题?提前致谢!

您正在记住 axios 创建的承诺。而是使用 useEffect() 进行调用并设置状态。除非您再次设置状态,否则数据不会改变:

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");
    });
}, []);

您正在 useMemo 调用中使用此箭头函数。

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

它 returns undefined。这是因为 axios.get returns a Promise 而你没有将它分配给任何东西并且你的箭头函数隐含地 returns undefined 因为它没有明确的return 声明。

试试这个:

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

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

这里useEffect是在组件初始渲染后调用的,即调用axios.get。它是一个异步函数,因此 useEffect 在调用后立即调用 returns。当 axios.get 异步调用成功时,它会调用 then 调用中的箭头函数,该函数将响应中的数据分配给 data 状态变量。

您已经定义了一个 promise 并且没有返回它,所以代码没有等待 promise 解决。尝试使用 async await 语法,这样更容易可视化流程。

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

这些解决方案对我来说并不成功,因为我为项目构建了我的模式。我用 redux dispatch 的数据请求(所以 redux-thunk)实际上我使用 redux-toolkit 来进行快速开发。

我是这样解决的;

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>

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

我的 package.json 规格是这样的;

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