上下文不更新值

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>
    </>
  )
}