如何将 useMemo 与外部 API 一起使用?
How to use useMemo with an external API?
我正在使用 react-table
库进行过滤和分页。我正在使用 Node
从自定义 API 请求数据,并使用来自 react-table
的 useTable
钩子呈现它。 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",
我正在使用 react-table
库进行过滤和分页。我正在使用 Node
从自定义 API 请求数据,并使用来自 react-table
的 useTable
钩子呈现它。 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",