微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

同步更新所有使用它的组件的自定义钩子

如何解决同步更新所有使用它的组件的自定义钩子

我正在尝试在 React 中创建一个使用自定义钩子的 Switch 组件。我希望其他组件使用相同的自定义钩子,以便在单击 Switch 时更新它们。为此,我创建了这个自定义钩子:

function usetoggle() {
  const [isToggled,setIsToggled] = useState(false);

  const toggle = React.useCallback(
    () => setIsToggled(state => !state),[setIsToggled],);

  return [isToggled,toggle];
}

然后在我想订阅这个自定义钩子的 Switch 组件中:

const Switch = () => {
  const [isToggled,toggle] = usetoggle();
  return (
         <Switch
          onChange={toggle as any}
          checked={isToggled as boolean}
          ...
        />

  );
}

然后在根据开关是否切换而改变值的组件中,我有

const PricingHeader = () => {
   // Subscribe to switch's event
   const [isToggled,toggle] = usetoggle();

   return (<Price showSpecialPrice={isToggled} />);
}

问题?组件独立更新。我可以点击开关,当它的值被切换时,我看到它的呈现方式不同,但是当开关被切换时,我没有看到价格显示不同的价格。 价格在我点击开关时完全不受影响。

不确定我做错了什么?我想每次使用 usetoggle 时返回的 isToggled 状态都不同。我正在尝试做的事情有可能吗?

解决方法

有可能,您可以通过 Context API 共享您的 toggle 状态:

const SwitchContext = createContext();

function useToggle() {
  return useContext(SwitchContext);
}

const Switch = () => {
  const [isToggled,toggle] = useToggle();
  return <button onClick={toggle}>{isToggled ? "ON" : "OFF"}</button>;
};

const Price = () => {
  const [isToggled] = useToggle();
  return <>The price {isToggled ? "IS TOGGLED" : "IS NOT TOGGLED"}</>;
};

export default function App() {
  const [isToggled,toggle] = useReducer((p) => !p,false);
  return (
    <SwitchContext.Provider value={[isToggled,toggle]}>
      <Switch />
      <Price />
    </SwitchContext.Provider>
  );
}

Edit Singleton Hook Example

,

我可能会建议您为此使用 React Context。您可以使用 ToggleContext 创建一个 createContext 并将其与 useContext -

一起使用

const { createContext,useContext,useState } = React

const ToggleContext = createContext(false)

function useToggle (initialState) {
  const [isToggle,setToggle] = useState(initialState)
  const toggle = () => setToggle(value => !value)
  return [isToggle,toggle]
}

function MyApp () {
  const [isToggle,toggle] = useToggle(false)
  return (
    <ToggleContext.Provider value={isToggle}>
      <p>Click any switch</p>
      <Switch onClick={toggle} />
      <Switch onClick={toggle} />
      <Switch onClick={toggle} />
    </ToggleContext.Provider>
  )
}

function Switch ({ onClick }) {
  const isToggle = useContext(ToggleContext)
  return <input type="checkbox" onClick={onClick} checked={isToggle} />
}

ReactDOM.render(<MyApp />,document.querySelector("main"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<main></main>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。