如何解决如何在类组件中设置 zustand 状态
我正在开发一个站点,该站点使用 zustand 将全局状态存储在文件中。我需要能够在类组件中设置该状态。我可以使用钩子在功能组件中设置状态,但我想知道是否有办法将 zustand 与类组件一起使用。
如果有帮助,我已经为此问题创建了一个沙箱: https://codesandbox.io/s/crazy-darkness-0ttzd
function MyFunction() {
const { setPink } = useStore();
return (
<div>
<button onClick={setPink}>Set State Function</button>
</div>
);
}
我的状态存储在这里:
export const useStore = create((set) => ({
isPink: false,setPink: () => set((state) => ({ isPink: !state.isPink }))
}));
如何在类组件中设置状态?:
class MyClass extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<button
onClick={
{
/* setPink */
}
}
>
Set State Class
</button>
</div>
);
}
}
解决方法
类组件最接近于钩子的是高阶组件 (HOC) 模式。让我们将钩子 useStore
翻译成 HOC withStore
。
const withStore = BaseComponent => props => {
const store = useStore();
return <BaseComponent {...props} store={store} />;
};
我们可以在任何包裹在 withStore
中的类组件中将 store 作为 prop 访问。
class BaseMyClass extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { setPink } = this.props.store;
return (
<div>
<button onClick={setPink}>
Set State Class
</button>
</div>
);
}
}
const MyClass = withStore(BaseMyClass);
,
创建一个 React Context 提供者,函数式和基于类的组件都可以使用它。将 useStore
挂钩/状态移动到上下文提供程序。
store.js
import { createContext } from "react";
import create from "zustand";
export const ZustandContext = createContext({
isPink: false,setPink: () => {}
});
export const useStore = create((set) => ({
isPink: false,setPink: () => set((state) => ({ isPink: !state.isPink }))
}));
export const ZustandProvider = ({ children }) => {
const { isPink,setPink } = useStore();
return (
<ZustandContext.Provider
value={{
isPink,setPink
}}
>
{children}
</ZustandContext.Provider>
);
};
index.js
使用 ZustandProvider
组件包装您的应用程序。
...
import { ZustandProvider } from "./store";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<ZustandProvider>
<App />
</ZustandProvider>
</StrictMode>,rootElement
);
在两个组件中使用 ZustandContext
上下文
MyFunction.js
import React,{ useContext } from "react";
import { ZustandContext } from './store';
function MyFunction() {
const { setPink } = useContext(ZustandContext);
return (
<div>
<button onClick={setPink}>Set State Function</button>
</div>
);
}
MyClass.js
import React,{ Component } from "react";
import { ZustandContext } from './store';
class MyClass extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<button
onClick={this.context.setPink}
>
Set State Class
</button>
</div>
);
}
}
MyClass.contextType = ZustandContext;
在 ZustandContext
中交换新的 App
而不是直接使用 useStore
钩子。
import { useContext} from 'react';
import "./styles.css";
import MyClass from "./MyClass";
import MyFunction from "./MyFunction";
import { ZustandContext } from './store';
export default function App() {
const { isPink } = useContext(ZustandContext);
return (
<div
className="App"
style={{
backgroundColor: isPink ? "pink" : "teal"
}}
>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<MyClass />
<MyFunction />
</div>
);
}
如果您无法在 MyClass
组件上设置任何特定上下文,您可以使用 ZustandContext.Consumer
提供 setPink
回调作为道具。
<ZustandContext.Consumer>
{({ setPink }) => <MyClass setPink={setPink} />}
</ZustandContext.Consumer>
我的课堂
<button onClick={this.props.setPink}>Set State Class</button>
,
似乎它使用钩子,所以在课堂上你可以使用实例:
import { useStore } from "./store";
class MyClass extends Component {
render() {
return (
<div>
<button
onClick={() => {
useStore.setState({ isPink: true });
}}
>
Set State Class
</button>
</div>
);
}
}
,
这对我来说效果很好。 :
import React,{ Component } from "react";
import { useStore } from "./store";
class MyClass extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<button
onClick={
useStore.getState().setPink() // <-- Changed code
}
>
Set State Class
</button>
</div>
);
}
}
export default MyClass;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。