[英]React hook state - does not update component
So I'm running an app with the following setup:所以我正在运行一个具有以下设置的应用程序:
However with my current setup Component A does not rerender when the hook state does get a new item in the array, any ideas why this is happening?但是,在我当前的设置中,当钩子 state 确实在数组中获得一个新项目时,组件 A 不会重新呈现,有什么想法为什么会发生这种情况? Im providing some code for clearification:我提供了一些代码进行澄清:
const initialValue = [];
function getLocalStorageItem() {
const item = window.localStorage.getItem("queries");
return item ? JSON.parse(item) : initialValue;
}
function useLocalStorageQueryHistory() {
const { dispatch } = useAlertContext();
const [recentQueries, setRecentQueries] = useState(() => {
try {
return getLocalStorageItem();
} catch (error) {
dispatch(receiveMessageInterceptor(error));
return initialValue;
}
});
const setValue = (value) => {
try {
const recentQueries = getLocalStorageItem();
if (recentQueries.length >= 6) {
recentQueries.shift();
}
if (!recentQueries.some((query) => query.params === value.params)) {
window.localStorage.setItem(
"queries",
JSON.stringify([...recentQueries, value])
);
setRecentQueries([...recentQueries, value]);
}
} catch (error) {
dispatch(receiveMessageInterceptor(error));
}
};
return { recentQueries, setValue };
}
function RecentQueriesContainer() {
const { recentQueries } = useLocalStorageQueryHistory();
return (
<Container disableGutters>
{recentQueries.length ? (
recentQueries.map((item) => (
<Card key={`${item.params}`}>
<CardHeader
title={item.description}
/>
<Typography variant={"body2"}>
Mode: {item.params.split("&visualization=")[1]}
</Typography>
<Typography variant={"body2"}>Unit: {item.unit}</Typography>
</Card>
))
) : (
<Typography
variant={"subtitle2"}
color={"secondary"}
align={"center"}
mt={2}
>
No recent queries available
</Typography>
)}
</Container>
);
}
Simply uses the setter in useEffect只需在 useEffect 中使用 setter
useEffect(() => {
const {
features,
description,
unit,
amountOfCountries,
} = geoJsonFromSelectedStatistic;
if (features) {
setValue({
description,
unit,
amountOfCountries,
params: window.location.search,
});
}
}, [geoJsonFromSelectedStatistic]);
I believe that is because you're not creating a context.我相信这是因为您没有创建上下文。 Hooks don't share state by default, they only share state logic .默认情况下,钩子不共享 state,它们只共享 state逻辑。
So component A and B are using the same hook, but the state between them is different.所以组件 A 和 B 使用相同的钩子,但是它们之间的 state 是不同的。
Try creating a context and then using that to share the state.尝试创建一个上下文,然后使用它来共享 state。 It should work fine:)它应该可以正常工作:)
const AuthContext = createContext({});
export const AuthProvider = ({ children }) => {
const [isAuthenticated, setIsAuthenticated] = useState();
return (
<AuthContext.Provider value={{ isAuthenticated, setIsAuthenticated }}>
{children}
</AuthContext.Provider>
);
};
export function useAuth(){
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}
Something like this, where AuthProvider acts like your custom hook, whose values are the values exported by your hook.像这样的东西,其中 AuthProvider 就像您的自定义挂钩,其值是您的挂钩导出的值。 These will be available for any component in which the context is used with useAuth
这些将可用于上下文与useAuth
一起使用的任何组件
Don't forget to wrap your app with the <AuthProvider />
不要忘记使用<AuthProvider />
包装您的应用程序
I followed the approach of @thales-kenne and used the react context I already had a UI-context set up and extended it as follows:我遵循@thales-kenne 的方法并使用我已经设置了 UI 上下文的反应上下文并将其扩展如下:
const initialState = {
sidebarOpen: false,
...
recentQueries: getLocalStorageItem(),
};
function uiReducer(state = initialState, action) {
switch (action.type) {
case SIDEBAR: {
return {
...state,
sidebarOpen: action.sidebarOpen,
};
}
...
case RECENT_QUERIES: {
return {
...state,
recentQueries: action.recentQueries,
};
}
default:
return state;
}
}
export function getLocalStorageItem() {
const initialValue = [];
try {
const item = window.localStorage.getItem("queries");
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
}
export const setRecentQueries = (value) => {
try {
const recentQueries = getLocalStorageItem();
if (recentQueries.length >= 5) {
recentQueries.shift();
}
if (!recentQueries.some((query) => query.uri === value.uri)) {
window.localStorage.setItem(
"queries",
JSON.stringify([...recentQueries, value])
);
return {
type: RECENT_QUERIES,
recentQueries: [...recentQueries, value],
};
}
} catch (error) {
console.error(error);
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.