我最近使用钩子编写了一个表组件,每次页面加载时都会有一个对后端的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;
}
}
尝试使用redux工具箱中的redux重新选择包为此类任务构建自己的选择器。如果您想以redux方式管理状态,它是一个方便的工具。此外,我还建议遵循YouTube教程设置并使用redux重新选择。
正确的方法是使用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])
//...
}
您可以实现简单的验证来实现您想要的。我将假设您的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的链接:链接