我正在尝试学习 TypeScript。我可以在一个简单的页面上执行一个简单的 useState 挂钩。但是,当我希望能够使用上下文设置状态时,我无法让它正确设置状态,如它无法在页面上重新渲染所示。
应用程序.tsx
export interface User {
isSubscribed: boolean;
name: string;
}
const App: React.FC = () => {
const [user, setUser] = useState<User>({
isSubscribed: true,
name: 'You',
})
return(
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<DashboardContext.Provider value={{user, setUser}}>
<Route exact path="/home">
<Home />
</Route>
<Route exact path="/">
<Redirect to="/home" />
</Route>
</DashboardContext.Provider>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
)
};
export default App;
context.tsx:
export interface DashboardInterface {
user: User
setUser: Dispatch<SetStateAction<User>>
}
export const DashboardContext = createContext<DashboardInterface>(undefined);
export function useUserContext() {
const {user, setUser} = useContext(DashboardContext)
if (user===undefined){
throw new Error("useUserContext must be used with a Dashboard Context")
}
return {user, setUser}
}
Home.tsx
const Home: React.FC = () => {
interface Thing {
title: string;
nickname: string
}
const {user, setUser }= useUserContext()
const [thing, setThing]=useState<Thing>({
title: "Mr",
nickname: "Morale",
})
useEffect(() => {
console.log("in the useEffect")
},[user])
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>User {user.name} {thing.nickname}</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Blank</IonTitle>
</IonToolbar>
</IonHeader>
<IonButton onClick={()=>{setUser({isSubscribed: false, name: "Pete"}); console.log('clicked!', user); setThing({title: "Mrs", nickname:"Morales"})}}>
Change Name
</IonButton>
<ExploreContainer />
</IonContent>
</IonPage>
);
};
export default Home;
在 Home.tsx 中,我有一个按钮,当我按下它时,我希望它将 user.name 更改为“Pete”,将 Thing.nickname 更改为“Morales”,如组件中所示。
当我点击按钮时。只有 thing.nickname 从 Morale 更改为 Morales。 (事情是我在 Home.tsx 页面上设置的)。但是 user.name 与“You”保持不变(用户是我在 App.tsx 和 context.tsx 上设置的内容。)因此,我认为我在使用上下文时做错了。关于我做错了什么有什么想法吗?
该问题可能与 useState hook 是异步的有关。尝试类似下面的代码来观察您的用户变量。当用户值更改时它将运行。
useEffect(() => {
console.log('user:', user);
}, [user]);