【发布时间】:2022-12-18 21:02:43
【问题描述】:
我正在构建我的应用程序的设置页面,其中我们有一个通用的SettingsLayout(父组件),它用于所有设置页面。此布局的一个特殊性是它包含一个 ActionsBar,其中存在用于保存数据的提交/保存按钮。
然而,这个SettingsLayout的内容对于每个页面都是不同的,因为每个页面都有不同的形式和不同的交互方式。为了将数据持久化到后端,我们使用了在子组件之一中调用的 Apollo Mutation,这就是无法访问 ActionsBar 保存按钮的原因。
对于这个实现,我认为 React Context 是最合适的方法。一开始,我想到了使用 Ref,在每次不同的渲染中使用提交处理函数更新它,以了解变化。
我已经实现了一个 codesandbox,其中包含一个非常小且精简的应用程序示例,以试图更好地说明和阐明我尝试实现的内容。
https://codesandbox.io/s/romantic-tdd-y8tpj8?file=/src/App.tsx
这种方法有什么注意事项吗?
import React from "react";
import "./styles.css";
type State = {
onSubmit?: React.MutableRefObject<() => void>;
};
type SettingsContextProviderProps = {
children: React.ReactNode;
value?: State;
};
type ContextType = State;
const SettingsContext = React.createContext<ContextType | undefined>(undefined);
export const SettingsContextProvider: React.FC<SettingsContextProviderProps> = ({
children
}) => {
const onSubmit = React.useRef(() => {});
return (
<SettingsContext.Provider value={{ onSubmit }}>
{children}
</SettingsContext.Provider>
);
};
export const useSettingsContext = (): ContextType => {
const context = React.useContext(SettingsContext);
if (typeof context === "undefined") {
/*throw new Error(
"useSettingsContext must be used within a SettingsContextProvider"
);*/
return {};
}
return context;
};
function ExampleForm() {
const { onSubmit } = useSettingsContext();
const [input1, setInput1] = React.useState("");
const [input2, setInput2] = React.useState("");
onSubmit.current = () => {
console.log({ input1, input2 });
};
return (
<div className="exampleForm">
<input
placeholder="Input 1"
onChange={(event) => setInput1(event.target.value)}
/>
<input
placeholder="Input 2"
onChange={(event) => setInput2(event.target.value)}
/>
</div>
);
}
function ActionsBar() {
const { onSubmit } = useSettingsContext();
return (
<section className="actionsBar">
<strong>SETTINGS</strong>
<button onClick={() => onSubmit?.current()}>Save</button>
</section>
);
}
export default function App() {
return (
<div className="App">
<SettingsContextProvider>
<ActionsBar />
<ExampleForm />
</SettingsContextProvider>
</div>
);
}
【问题讨论】:
-
将使用此(或任何更好的方法)的模式的另一个示例是典型的浮动操作按钮。
标签: reactjs typescript react-hooks next.js react-context