上下文不更新值
Context doesn't update the value
我有这样的背景
type ScanContextState = {
confirm: boolean;
toggleConfirm: () => void;
};
const defaultState: ScanContextState = {
confirm: false,
toggleConfirm: () => {},
};
export const ConfirmScanningContext =
createContext<ScanContextState>(defaultState);
export const ScannigProvider: FC = ({ children }) => {
const [confirm, setConfirm] = useState(defaultState.confirm);
const toggleConfirm = () => {
setConfirm(!confirm);
};
return (
<ConfirmScanningContext.Provider value={{ confirm, toggleConfirm }}>
{children}
</ConfirmScanningContext.Provider>
);
};
当扫描完成时,我会在屏幕上调用 toggleConfirm toggleConfirm();
这是我的应用程序的根
import PaymentBottomSheet from "./PaymentBottomSheet";
import MainStackNavigator from "./MainStackNavigator";
import { ScannigProvider } from "./Contexts";
import { ConfirmScanningContext } from "./Contexts";
const Root: React.FC = () => {
const [showScan, setScan] = useState(false);
const { confirm, toggleConfirm } = useContext(ConfirmScanningContext);
return (
<>
<ScannigProvider>
<IconRegistry icons={EvaIconsPack} />
<ApplicationProvider {...eva} theme={{ ...eva.light, ...theme }}>
<NavigationContainer>
<MainStackNavigator
setScan={setScan}
/>
{confirm && <PaymentBottomSheet setScan={setScan} />}
</NavigationContainer>
</ApplicationProvider>
</ScannigProvider>
</>
);
};
export default Root;
我想在 confirm 为 true 时查看 PaymentBottomSheet,但是我不知道为什么它永远不会变为 true,尽管我像之前说的那样切换它。我不熟悉使用打字稿的上下文,所以请有人向我解释为什么它没有更新!
上下文提供者需要在组件树中高于上下文消费者。在 Root
中,您正在使用上下文:
const { confirm, toggleConfirm } = useContext(ConfirmScanningContext);
...但是树上没有比 Root
更高的提供程序,因此您将获得上下文的默认值。该默认值有一个用于 toggleConfirm 的空函数,因此当您调用它时什么也不会发生。
您需要分解您的组件,以便提供程序可以位于顶部。例如:
const Root: React.FC = () => {
return (
<ScannigProvider>
<SomeOtherComponent/>
</ScannigProvider>
);
}
const SomeOtherComponent: React.FC = () => {
const [showScan, setScan] = useState(false);
const { confirm, toggleConfirm } = useContext(ConfirmScanningContext);
return (
<>
<IconRegistry icons={EvaIconsPack} />
<ApplicationProvider {...eva} theme={{ ...eva.light, ...theme }}>
<NavigationContainer>
<MainStackNavigator
setScan={setScan}
/>
{confirm && <PaymentBottomSheet setScan={setScan} />}
</NavigationContainer>
</ApplicationProvider>
</>
)
}
我有这样的背景
type ScanContextState = {
confirm: boolean;
toggleConfirm: () => void;
};
const defaultState: ScanContextState = {
confirm: false,
toggleConfirm: () => {},
};
export const ConfirmScanningContext =
createContext<ScanContextState>(defaultState);
export const ScannigProvider: FC = ({ children }) => {
const [confirm, setConfirm] = useState(defaultState.confirm);
const toggleConfirm = () => {
setConfirm(!confirm);
};
return (
<ConfirmScanningContext.Provider value={{ confirm, toggleConfirm }}>
{children}
</ConfirmScanningContext.Provider>
);
};
当扫描完成时,我会在屏幕上调用 toggleConfirm toggleConfirm();
这是我的应用程序的根
import PaymentBottomSheet from "./PaymentBottomSheet";
import MainStackNavigator from "./MainStackNavigator";
import { ScannigProvider } from "./Contexts";
import { ConfirmScanningContext } from "./Contexts";
const Root: React.FC = () => {
const [showScan, setScan] = useState(false);
const { confirm, toggleConfirm } = useContext(ConfirmScanningContext);
return (
<>
<ScannigProvider>
<IconRegistry icons={EvaIconsPack} />
<ApplicationProvider {...eva} theme={{ ...eva.light, ...theme }}>
<NavigationContainer>
<MainStackNavigator
setScan={setScan}
/>
{confirm && <PaymentBottomSheet setScan={setScan} />}
</NavigationContainer>
</ApplicationProvider>
</ScannigProvider>
</>
);
};
export default Root;
我想在 confirm 为 true 时查看 PaymentBottomSheet,但是我不知道为什么它永远不会变为 true,尽管我像之前说的那样切换它。我不熟悉使用打字稿的上下文,所以请有人向我解释为什么它没有更新!
上下文提供者需要在组件树中高于上下文消费者。在 Root
中,您正在使用上下文:
const { confirm, toggleConfirm } = useContext(ConfirmScanningContext);
...但是树上没有比 Root
更高的提供程序,因此您将获得上下文的默认值。该默认值有一个用于 toggleConfirm 的空函数,因此当您调用它时什么也不会发生。
您需要分解您的组件,以便提供程序可以位于顶部。例如:
const Root: React.FC = () => {
return (
<ScannigProvider>
<SomeOtherComponent/>
</ScannigProvider>
);
}
const SomeOtherComponent: React.FC = () => {
const [showScan, setScan] = useState(false);
const { confirm, toggleConfirm } = useContext(ConfirmScanningContext);
return (
<>
<IconRegistry icons={EvaIconsPack} />
<ApplicationProvider {...eva} theme={{ ...eva.light, ...theme }}>
<NavigationContainer>
<MainStackNavigator
setScan={setScan}
/>
{confirm && <PaymentBottomSheet setScan={setScan} />}
</NavigationContainer>
</ApplicationProvider>
</>
)
}