我最近使用 hooks 编写了一个表格组件,每次页面加载时都会对后端进行 API 调用,因此同时会显示一个正在加载的 Spinner,直到有来自 API 的响应。我使用 redux 作为状态管理,所以当有来自 API 的响应时,会调度一个 Action 并更新状态。
所以这里的问题是,通常在类组件中我们可以使用比较 prevProps 和 nextProps
componentDidUpdate(prevProps){
if(this.props.someState !== prevProps.someState){
// do something
}
}
但我不确定如何使用 Hooks 来实现相同的目标。我还提到了这个stackoverflow问题How to compare oldValues and newValues on React Hooks useEffect?
但这个解决方案似乎不适用于我的情况。我确实尝试过创建自定义 Hook 使用上一页 并创建 引用比较当前值 ,这并没有解决我的问题。
这是我的部分代码。
let loading = true;
let tableData = useSelector((state) => {
if (
state.common.tableDetails.data &&
state.common.tableDetails.status === true
) {
loading = false;
return state.common.tableDetails.data;
}
if (
state.common.tableDetails.data &&
state.common.tableDetails.status === false
) {
loading = true;
}
return [];
});
// table component
<Fragment>
{
loading === true ? <Spinner /> : <TableComponent tableData={tableData }/>
}
</Fragment>
因此,每当组件加载时,如果 redux state 中存在任何数据,则会显示该数据,并且不会对 prevProps 和 nextProps 进行比较,因为 Loading spinner 不会出现,并且在新调用的 api state 响应之后将是更新和新数据将显示在表中。更新 1:
这是 dispatch 和 action 以及 reducer 的代码
useEffect(() => {
dispatch(fetchDetails(params.someID));
}, [dispatch, params.someID]);
Action 文件export const fetchDetails = (data) => (dispatch) => {
axios
.post(
`${SomeURL}/fetchAll`,
data
)
.then((res) => {
if (res.data.status) {
dispatch({
type: FETCH_DETAILS,
payload: res.data,
});
}
})
.catch((err) => console.log(err));
};
reducer 文件const initialState = {
tableDetails: {},
};
export default function (state = initialState, action) {
switch (action.type) {
case FETCH_DETAILS:
return {
...state,
tableDetails: action.payload,
};
default:
return state;
}
}
最佳答案
您可以实现简单的验证来实现您想要的。
我会假设你的 tableData
有一个 id
,那么您可以像这样进行验证:
useEffect(() => {
// don't fetch the same table
if(tableData?.id !== params.someID {
dispatch(fetchDetails(params.someID));
}
}, [dispatch, params.someID, tableData?.id]);
更新 1
要将以前的表数据与新提取的数据进行比较,您可以在操作创建器中执行此操作:
loading
状态到 redux 存储。 getState
Action 创建者接收的第二个参数函数(假设您使用的是 redux-thunk)tableData
存储中的数据(上一页 tableData
)。 loading
状态。 export const fetchDetails = (data) => (dispatch, getState) => {
axios
.post(
`${SomeURL}/fetchAll`,
data
)
.then((res) => {
if (res.data.status) {
const prevTableData = getState().tableData;
// compare prev and new table data
if(isDiff(prevTableData, res.data) {
// Do something...
}
dispatch({
type: FETCH_DETAILS,
payload: res.data,
});
}
})
.catch((err) => console.log(err));
};
关于javascript - 如何在 Hook 中比较来自 react redux 状态的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68896074/