jar*_*vak 7 javascript reactjs react-redux react-state-management react-hooks
我最近使用 hooks 编写了一个 table 组件,每次页面加载时都会对后端进行 API 调用,因此同时会显示一个加载 Spinner,直到 API 响应。我使用 redux 作为状态管理,所以当有来自 API 的响应时,会调度一个动作并更新状态。所以这里的问题是,通常在类组件中我们可以使用比较 prevProps 和 nextProps
componentDidUpdate(prevProps){
if(this.props.someState !== prevProps.someState){
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
但我不确定如何使用 Hooks 实现相同的目标。我还提到了这个 stackoverflow 问题 How to compare oldValues and newValues on React Hooks useEffect?
但是这个解决方案在我的情况下似乎不起作用。我确实尝试过创建自定义钩子usePrevious并创建一个ref 来比较当前值,但这并没有解决我的问题。
这是我的部分代码。
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 [];
});
Run Code Online (Sandbox Code Playgroud)
// table component
<Fragment>
{
loading === true ? <Spinner /> : <TableComponent tableData={tableData }/>
}
</Fragment>
Run Code Online (Sandbox Code Playgroud)
因此,每当组件加载时,如果 redux state 中存在任何数据,则会显示该数据,并且不会对 prevProps 和 nextProps 进行比较,因为不会显示加载微调器,并且在响应新调用的 api 状态之后将是更新和新数据将显示在表中。
更新 1: 这是 dispatch 和 action 以及 reducer 的代码
useEffect(() => {
dispatch(fetchDetails(params.someID));
}, [dispatch, params.someID]);
Run Code Online (Sandbox Code Playgroud)
动作文件
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));
};
Run Code Online (Sandbox Code Playgroud)
减速器文件
const initialState = {
tableDetails: {},
};
export default function (state = initialState, action) {
switch (action.type) {
case FETCH_DETAILS:
return {
...state,
tableDetails: action.payload,
};
default:
return state;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以实施简单的验证来实现您想要的。我假设你tableData有一个id,那么你可以这样验证:
useEffect(() => {
// don't fetch the same table
if(tableData?.id !== params.someID {
dispatch(fetchDetails(params.someID));
}
}, [dispatch, params.someID, tableData?.id]);Run Code Online (Sandbox Code Playgroud)
要将先前的表数据与新获取的表数据进行比较,您可以在操作创建器中执行此操作:
loading到 redux 存储。getState函数,这是动作创建者收到的第二个参数(假设您正在使用 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));
};Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
209 次 |
| 最近记录: |