【发布时间】:2019-11-10 09:31:41
【问题描述】:
我想使用 React Context 来保存表单的状态。 我可以为不同的表单使用相同的上下文吗?
这是我的示例代码。我在这个示例中使用 React Hooks API
在 FormContext.js
中...
import {FormReducer} from './FormReducer';
export const FormContext = React.createContext({});
const FormContextProvider = (props) => {
const formInit = props.value ? props.value : {};
const [formContext, dispatch] = useReducer(FormReducer, formInit);
return (
<FormContext.Provider value={{formContext, dispatch}}>
{props.children}
</FormContext.Provider>
);
}
export default FormContextProvider;
我的表单组件Form.js
...
import {FormContext} from './FormContext';
const Form = ({name, fields}) => {
const {formContext, dispatch} = useContext(FormContext);
const inputOnChange = (e, label) => {
let value = {};
value[label] = e.target.value;
dispatch({type:'ChangeField', value: value});
}
const renderInputs = () => {
return fields.map(field => {
return (
<div className="field">
<label>{field}</label>
<input
type="text"
value={formContext[field] ?formContext[field]: '' }
onChange={(e) => inputOnChange(e, field)}
/>
</div>
)}
);
}
return (
<div className="form">
<h3>{name}</h3>
<form>
{formContext ? renderInputs() : <React.Fragment/>}
</form>
</div>
);
}
Form.defaultProps = {
name: '',
fields: []
}
在 Index.js 我在 App 中包装了两个 Form 组件
const formOne = { name: 'Form One', fields: ['username', 'email'] };
const formTwo = { name: 'Form Two', fields: ['name', 'email'] };
<App>
<Form {...formOne}/>
<Form {...formTwo}/>
</App>
在 App.js 中,我有两个按钮来决定应该显示哪个表单
const App = (props) => {
const [form, setForm] = useState('');
const formBtnOnClick = (form) => {
setForm(form);
}
const renderForm = () => {
if (props.children) {
const selectForm = props.children.find(child => child.props.name.toLowerCase().includes(form));
if (selectForm) {
return (
<FormContextProvider>
{selectForm}
</FormContextProvider>
)
} else {
return (<React.Fragment></React.Fragment>);
}
}
}
return (
<div className="App">
App
<button onClick={(e) => formBtnOnClick('one')}>One</button>
<button onClick={(e) => formBtnOnClick('two')}>Two</button>
<Header text="Form" />
{renderForm()}
<Header />
</div>
);
}
当单击按钮后表单发生更改,但上下文没有重新呈现时, 以前形式的价值仍然存在。例如:我在form中修改了email的值,当我点击form二时,email的值依然存在。
我做错了什么还是有更好的选择来解决这个问题。
【问题讨论】:
-
大部分 React 表单库不使用顶层组件中的表单上下文。他们将上下文提供程序插入到表单组件中。这允许为不同的表单设置不同的状态,而无需手动清除状态。
-
具体应该怎么做?我想知道为什么上下文会一样,但是如果我将App.js的
renderForm()更改为props.children,这两种形式就不会有上下文问题。
标签: javascript reactjs react-context