Javascript 反应挂钩状态-不更新组件
因此,我正在运行具有以下设置的应用程序:Javascript 反应挂钩状态-不更新组件,javascript,reactjs,Javascript,Reactjs,因此,我正在运行具有以下设置的应用程序: 钩子-提供状态和设置器来更新状态 组件A-仅使用钩子中的状态,并显示钩子中的数据 组件B-仅使用setter并更新挂钩状态的状态 但是,对于我当前的设置组件,当钩子状态在数组中获得一个新项时,A不会重新加载,你知道为什么会发生这种情况吗?我提供了一些代码来进行澄清: 钩子 A部分 我相信这是因为你没有创造一个环境。默认情况下,钩子不共享状态,它们只共享状态逻辑 所以组件A和B使用相同的钩子,但是它们之间的状态不同 尝试创建一个上下文,然后使用它来共享
- 钩子-提供状态和设置器来更新状态
- 组件A-仅使用钩子中的状态,并显示钩子中的数据
- 组件B-仅使用setter并更新挂钩状态的状态
我相信这是因为你没有创造一个环境。默认情况下,钩子不共享状态,它们只共享状态逻辑 所以组件A和B使用相同的钩子,但是它们之间的状态不同 尝试创建一个上下文,然后使用它来共享状态。它应该可以正常工作:)
const AuthContext=createContext({});
导出常量AuthProvider=({children})=>{
常量[isAuthenticated,setIsAuthenticated]=useState();
返回(
{儿童}
);
};
导出函数useAuth(){
const context=useContext(AuthContext);
如果(!上下文){
抛出新错误(“必须在AuthProvider中使用useAuth”);
}
返回上下文;
}
类似于此,其中AuthProvider的行为类似于自定义钩子,其值是钩子导出的值。这些将可用于上下文与useAuth
别忘了用
包装你的应用程序。我遵循了@thales kenne的方法,使用了react上下文。我已经设置了一个UI上下文,并将其扩展如下:
UI-context.js
UI-actions.js
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>
);
}
useEffect(() => {
const {
features,
description,
unit,
amountOfCountries,
} = geoJsonFromSelectedStatistic;
if (features) {
setValue({
description,
unit,
amountOfCountries,
params: window.location.search,
});
}
}, [geoJsonFromSelectedStatistic]);
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;
}
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);
}
};