如何解决同步更新所有使用它的组件的自定义钩子
我正在尝试在 React 中创建一个使用自定义钩子的 Switch 组件。我希望其他组件使用相同的自定义钩子,以便在单击 Switch 时更新它们。为此,我创建了这个自定义钩子:
function usetoggle() {
const [isToggled,setIsToggled] = useState(false);
const toggle = React.useCallback(
() => setIsToggled(state => !state),[setIsToggled],);
return [isToggled,toggle];
}
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>
);
}
,
我可能会建议您为此使用 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 举报,一经查实,本站将立刻删除。