Pat*_*nny 3 reactjs ionic-framework react-hooks ionic-react use-reducer
我添加了一个上下文,其中包含useReducer
我的 Ionic React 应用程序的钩子。我看到一些奇怪的行为:当我通过调用更新上下文值时dispatch
,页面上的消费者组件将被更新,但选项卡栏上完全相同的组件不会更新。
我按照这个教程进行了操作。
当我添加console.log
语句来检查组件是否正在重新加载时,我发现<TabBarCounter>
即使上下文值已更改,放置在选项卡栏 ( ) 中的组件也没有重新加载。
当我添加语句来检查上下文提供程序中的重新渲染时,我发现调用console.log
a 时它也不会重新渲染。dispatch
上下文似乎是在本地更新,而不是全局更新。这个答案中有一条评论:
您正在使用减速器正确更新状态,但它只会更新本地组件状态,而不是全局上下文状态。
这听起来很像我在这里遇到的问题。
这是一些代码:
MyContext.tsx
export const CountContext = React.createContext<any>({} as {
countState: CountState,
countDispatch: React.Dispatch<CountReducerActions>,
});
interface MyProps {
children: JSX.Element,
}
const reducer = (countState: CountState, action: CountReducerActions) => {
switch (action.type) {
case 'add1': {
countObject.total += 1;
return countObject;
}
default: {
throw new Error();
}
}
};
export const CountContextProvider: React.VFC<MyProps> = ({ children }: MyProps) => {
const [countState, countDispatch] = useReducer(
reducer,
{
total: 0,
},
);
return (
<CountContext.Provider value={{ countState, countDispatch }}>
{children}
</CountContext.Provider>
);
};
Run Code Online (Sandbox Code Playgroud)
我如何更新上下文
const { countState, countDispatch } = useContext(CountContext);
countDispatch({ type: 'add1' });
Run Code Online (Sandbox Code Playgroud)
MyComponentThatDoesNotGetRerendered.tsx
import React, { useContext } from 'react';
import { IonBadge } from '@ionic/react';
import { CountContext } from '../../context/CountContext';
const TabBarCounter: React.VFC = () => {
const [countState] = useContext(CountContext);
return (
<IonBadge>
{countState.total}
</IonBadge>
);
};
export default TabBarCounter;
Run Code Online (Sandbox Code Playgroud)
路由器.tsx
<CountContextProvider>
<IonReactRouter>
<AppTabBar>
<IonRouterOutlet>
<Route exact path={myPageRoute}>
<MyPage />
</Route>
<Route>
<PageError404 />
</Route>
</IonRouterOutlet>
</AppTabBar>
</IonReactRouter>
</CountContextProvider>
Run Code Online (Sandbox Code Playgroud)
AppTabBar.tsx
const AppTabBar: React.VFC<MyProps> = ({ children }: MyProps) => {
const [userObject] = useContext(UserContext);
return (
<IonTabs>
{children}
<IonTabBar slot="bottom" id="appTabBar">
<IonTabButton tab="tab-settings" href={routeTabSettings}>
<IonLabel>Settings</IonLabel>
</IonTabButton>
<IonTabButton
tab="tab-count"
href={routeTabCount}
>
<TabBarReviewCounter />
<IonLabel>Count</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
);
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,当 中的上下文更新时<MyPage>
,<TabBarCounter>
内部的<AppTabBar>
不会更新,但<TabBarCounter>
内部<MyPage>
会更新。
如何正确使用更新上下文,useReducer()
以便当我更新上下文值时,该上下文的所有使用者都会更新?
看看你的减速机。您无需以不可变的方式修改状态,只需覆盖属性而不创建新的引用,因此上下文值永远不会更新。
由于某些原因(本地状态更改、道具更改等),某些组件在重新渲染时可能会“看到”此更改。它们将到达上下文,查看提供的对象并查看新值。
要修复此问题,请使用扩展运算符使用先前状态的键和更新的属性创建新对象total
。
case 'add1': {
return {
...countObject,
total: countObject.total + 1,
};
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1890 次 |
最近记录: |