javascript - 如何在 Hook 中比较来自 react redux 状态的值

标签 javascript reactjs react-redux react-hooks react-state-management

我最近使用 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/

    相关文章:

    javascript - React.js - 可拖动元素上的setDragImage

    reactjs - 可以从 Redux reducer 中发出 REST API 请求吗?

    javascript - ReactJS:从表单获取输入

    javascript - Redux:Reducer 需要其他 Reducer 的状态?

    javascript - ionic 2中的垂直滑动/拖动手势

    javascript - 在 iffe 中访问 'this' 上下文

    reactjs - NextJS "Warning: Each child in a list should have a unique ' key ' prop"错误

    javascript - Adobe Creative SDK 图像编辑器中没有未保存的更改提示

    javascript - 将 Mongoose 模式导入另一个模式文件使导入的模式未定义

    用于匹配正整数和负整数的 Javascript RegEx