当前位置: 首页 > 知识库问答 >
问题:

如何比较钩子中反应还原状态的值

公良云
2023-03-14

我最近使用钩子编写了一个表组件,每次页面加载时都会有一个对后端的API调用,因此同时会显示一个加载微调器,直到有来自API的响应为止。我使用redux作为状态管理,所以当有来自API的响应时,将调度一个操作并更新状态。所以这里的问题是,通常在类组件中,我们可以使用

componentDidUpdate(prevProps){
  if(this.props.someState !== prevProps.someState){
      // do something
    }
}

但是我不知道如何使用钩子实现同样的效果。我还提到了这个stackoverflow问题如何比较反应挂钩的旧值和新值使用效果?

但这个解决方案在我的情况下似乎不起作用。我确实尝试过创建自定义钩子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 [];
  });

// table component

<Fragment>
  { 
   loading === true ? <Spinner />  :  <TableComponent tableData={tableData }/>
   }
</Fragment>

因此,每当组件加载时,如果redux状态中存在任何数据,则会显示该数据,并且不会对prevProps和nextProps进行比较,因为加载微调器不会显示,并且在新调用的api状态响应之后,将更新,新数据将显示在表中。

更新1:这是调度、操作和减速器的代码

 useEffect(() => {
    
    dispatch(fetchDetails(params.someID));

  }, [dispatch, params.someID]);

动作文件

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));
};

减速器锉

const initialState = {
  tableDetails: {},
};

export default function (state = initialState, action) {
  switch (action.type) {
    case FETCH_DETAILS:
      return {
        ...state,
        tableDetails: action.payload,
      };

    default:
      return state;
  }
}


共有3个答案

苏鸿志
2023-03-14

尝试使用redux工具箱中的redux重新选择包为此类任务构建自己的选择器。如果您想以redux方式管理状态,它是一个方便的工具。此外,我还建议遵循YouTube教程设置并使用redux重新选择。

钦英发
2023-03-14

正确的方法是使用redux重新选择包https://github.com/reduxjs/reselect. Redux团队推荐它。

重选是专为这类场景设计的。它还在引擎盖下使用记忆。您可以制作自定义选择器,并在这样的场景中使用它们。

您可以为所有重选函数创建一个单独的文件,就像这样

//select file (eg: selectors.js)
import { createSelector } from "reselect";

const tableDetails = state => state.common.tableDetails;

function checkDataFunction(details){
    if (
      details.data &&
      details.status === true
    ) {
      return {
        loading: false,
        data: details.data
      }
    }
   
    else if (
      details.data &&
      details.status === false
      
    ) {
      return {
        loading: true,
        data: []
      }
    }

    return {
      loading: true,
      data: []
    };
}

//redux selector
//enables you to make your own custom selector
export const checkData = createSelector(
  tableDetails,
  checkDataFunction
);

现在,在您想要使用它的主组件文件中,只需导入它并将其用作任何其他选择器

//main component file (eg: App.js)
import {checkData} from './selectors';


export default function App(){
  const tableData = useSelector(checkData);

  useEffect(() => {
    //continue with your logic here
  },[tableData.loading])

  //...
}
严斌
2023-03-14

您可以实现简单的验证来实现您想要的。我将假设您的tableData有一个id,那么您可以这样验证:

useEffect(() => {
    // don't fetch the same table
    if(tableData?.id !== params.someID {
      dispatch(fetchDetails(params.someID));
    }
}, [dispatch, params.someID, tableData?.id]);
 类似资料:
  • 如何在功能组件中使用preState和use效果?我被告知要更新类组件到功能组件,我被困在了组件的didUpdate部分

  • 我正在尝试新的hooks功能,并坚持认为我的状态没有更新。 实际上,状态已更新(我可以在console.log中看到更新的值,并且我的组件会重新运行useEffect),但是useEffect方法使用我的旧状态,并仅将签名保存给第一个用户,而活动用户在状态中确实发生了更改。 我想过添加useCallback,并将我的方法移动到use效果或组件本身,但我可以设法让它工作。 状态: 这是我的效果: 这

  • 在React的这篇文档中,据说 shallowCompare对current props和nextProps对象以及current state和nextState对象执行浅层相等性检查。 我无法理解的是,如果它简单地比较了对象,那么componentupdate方法应该总是返回true,就像 如果我们没有改变状态,那么比较将始终返回false,因此shouldComponent更新将始终返回tru

  • 在这个项目中,我使用了反应钩,这个片段用来改变项目的颜色主题,但有一个问题,我无法解决。常量lightTheme={...} Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eusmod tempor incidunt ut labore et dolore magna aliqua. 我的减速器:

  • 我有一个名为的组件,还有一个子组件名为。智利组件有一个名为的状态。我需要从AvailabiltyCalendar组件访问该状态并获取该状态值。我该怎么做呢。 可用压路机组件 DatePicker组件

  • 我有一个函数反应组件,它有一个从10000开始到0的计数器。 我正在组件安装期间使用useEffect挂钩设置setInterval回调。然后,回调更新计数器状态。 但是不知道为什么,值从来没有减少过。每次回调运行为10000。 (我正在使用react 功能组件如下所示: 这里是codesandbox的链接:链接