我目前正在将 React 与 React Router 和 React Relay 一起使用。其中每一个都有更新/传递数据的方法。使用
useState
进行 React,使用其 PushState 包装器 (location.state
) 进行 React Router,使用其 updater()
方法进行 Relay。
但是我不确定应该使用哪个来处理全局状态(如果有的话)。我的应用程序的所有页面都需要一个特定的 ID,它不是会话。想象一个包含 5 个步骤的表单。步骤 1 没有 ID,步骤 2 在成功提交时获取 ID,现在在步骤 3-5 中需要将该 ID 呈现为隐藏输入(作为示例)。我们称其为formId
。
location.state
来传递它,但感觉不对。相反,我觉得一旦设置好,我应该有办法得到这个
formId
。如果 formId
为空,则将其发送到步骤 1,如果不为空,则加载当前页面/路由。当然,我可以使用window.formId
,但这似乎是最错误的。
看起来像这样
// FormIdContext.tsx
import React, { createContext, useState, useContext } from 'react';
interface FormIdContextType {
formId: string | null;
setFormId: (formId: string | null) => void;
}
const FormIdContext = createContext<FormIdContextType | undefined>(undefined);
// A custom hook to consume the FormIdContext
export function useFormIdContext(): FormIdContextType {
const context = useContext(FormIdContext);
if (!context) {
throw new Error('useFormIdContext must be used within a FormIdContext.Provider');
}
return context;
}
export function FormIdProvider(props: React.PropsWithChildren<{}>) {
const [formId, setFormId] = useState<string | null>(null);
return (
<FormIdContext.Provider value={{ formId, setFormId }}>
{props.children}
</FormIdContext.Provider>
);
}
然后在我的路由器中
// App.tsx
import React, { useState } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Step1 from './Step1';
import Step2 from './Step2';
import Step3 from './Step3';
import FormIdContext from './FormIdContext';
function App() {
const [formId, setFormId] = useState<string | null>(null);
return (
<Router>
<FormIdContext.Provider value={{ formId, setFormId }}>
<Route path="/step1" component={Step1} />
<Route path="/step2" component={Step2} />
<Route path="/step3" component={Step3} />
</FormIdContext.Provider>
</Router>
);
}
export default App;
然后我可以像这样获取和设置这些值
// Step3.tsx
import React from 'react';
import { useHistory } from 'react-router-dom';
import { useFormIdContext } from './FormIdContext';
function Step3() {
const history = useHistory();
const { formId, setFormId } = useFormIdContext();
const handleFormSubmission = () => {
// Assuming you have the form data and you want to perform some submission logic
// Once the submission is successful and you get the formId, you can update the state
const newFormId = 'new_generated_form_id';
setFormId(newFormId);
// Optionally, you can navigate to another page or perform other actions
// Here, we simply go back to Step2 as an example
history.push('/step2');
};
return (
<div>
{/* Your Step 3 content that may use formId */}
<h1>Step 3</h1>
<p>Current formId: {formId}</p>
<button onClick={handleFormSubmission}>Submit Form</button>
</div>
);
}
export default Step3;