有条件地渲染 2 个 Formik 组件不会改变初始值
Conditionally rendering 2 Formik components doesn't change initial values
我有条件地渲染 2 个 <Formik/>
组件,但值没有改变
function App() {
const [state, setState] = useState(true);
return (
<div>
<button
onClick={() => {
setState((s) => !s);
}}
>
toggle
</button>
<h1>Sign Up</h1>
{state ? (
<Formik
initialValues={{
firstName: "",
lastName: "",
email: ""
}}
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
alert(JSON.stringify(values, null, 2));
}}
>
<Form>
<div>
<label htmlFor="firstName">First Name</label>
<Field id="firstName" name="firstName" placeholder="Jane" />
</div>
<div>
<label htmlFor="lastName">Last Name</label>
<Field id="lastName" name="lastName" placeholder="Doe" />
</div>
<div>
<label htmlFor="email">Email</label>
<Field
id="email"
name="email"
placeholder="jane@acme.com"
type="email"
/>
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
) : (
<Formik
initialValues={{
fn: "",
ln: ""
}}
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
alert(JSON.stringify(values, null, 2));
}}
>
<Form>
<div>
<label htmlFor="fn">F N</label>
<Field id="fn" name="fn" placeholder="Jane" />
</div>
<div>
<label htmlFor="ln">L N</label>
<Field id="ln" name="ln" placeholder="Doe" />
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
)}
</div>
);
}
https://codesandbox.io/s/nifty-fast-4ef5r?file=/src/App.js
在上面的codeandbox中尝试切换并提交
切换后初始值保持不变
内部发生了什么导致这种行为?
React / Formik 必须在两个实例中引用相同的上下文,因为它们在相同的位置呈现。要解决此问题,请在两个表单上放置不同的 'key' 属性。
function App() {
const [state, setState] = useState(true);
return (
<div>
<button
onClick={() => {
setState((s) => !s);
}}
>
toggle
</button>
<h1>Sign Up</h1>
{state ? (
<Formik
key="1"
initialValues={{
firstName: "",
lastName: "",
email: ""
}}
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
alert(JSON.stringify(values, null, 2));
}}
>
<Form>
<div>
<label htmlFor="firstName">First Name</label>
<Field id="firstName" name="firstName" placeholder="Jane" />
</div>
<div>
<label htmlFor="lastName">Last Name</label>
<Field id="lastName" name="lastName" placeholder="Doe" />
</div>
<div>
<label htmlFor="email">Email</label>
<Field
id="email"
name="email"
placeholder="jane@acme.com"
type="email"
/>
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
) : (
<Formik
key="2"
initialValues={{
fn: "",
ln: ""
}}
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
alert(JSON.stringify(values, null, 2));
}}
>
<Form>
<div>
<label htmlFor="fn">F N</label>
<Field id="fn" name="fn" placeholder="Jane" />
</div>
<div>
<label htmlFor="ln">L N</label>
<Field id="ln" name="ln" placeholder="Doe" />
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
)}
</div>
);
}
我有条件地渲染 2 个 <Formik/>
组件,但值没有改变
function App() {
const [state, setState] = useState(true);
return (
<div>
<button
onClick={() => {
setState((s) => !s);
}}
>
toggle
</button>
<h1>Sign Up</h1>
{state ? (
<Formik
initialValues={{
firstName: "",
lastName: "",
email: ""
}}
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
alert(JSON.stringify(values, null, 2));
}}
>
<Form>
<div>
<label htmlFor="firstName">First Name</label>
<Field id="firstName" name="firstName" placeholder="Jane" />
</div>
<div>
<label htmlFor="lastName">Last Name</label>
<Field id="lastName" name="lastName" placeholder="Doe" />
</div>
<div>
<label htmlFor="email">Email</label>
<Field
id="email"
name="email"
placeholder="jane@acme.com"
type="email"
/>
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
) : (
<Formik
initialValues={{
fn: "",
ln: ""
}}
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
alert(JSON.stringify(values, null, 2));
}}
>
<Form>
<div>
<label htmlFor="fn">F N</label>
<Field id="fn" name="fn" placeholder="Jane" />
</div>
<div>
<label htmlFor="ln">L N</label>
<Field id="ln" name="ln" placeholder="Doe" />
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
)}
</div>
);
}
https://codesandbox.io/s/nifty-fast-4ef5r?file=/src/App.js
在上面的codeandbox中尝试切换并提交
切换后初始值保持不变
内部发生了什么导致这种行为?
React / Formik 必须在两个实例中引用相同的上下文,因为它们在相同的位置呈现。要解决此问题,请在两个表单上放置不同的 'key' 属性。
function App() {
const [state, setState] = useState(true);
return (
<div>
<button
onClick={() => {
setState((s) => !s);
}}
>
toggle
</button>
<h1>Sign Up</h1>
{state ? (
<Formik
key="1"
initialValues={{
firstName: "",
lastName: "",
email: ""
}}
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
alert(JSON.stringify(values, null, 2));
}}
>
<Form>
<div>
<label htmlFor="firstName">First Name</label>
<Field id="firstName" name="firstName" placeholder="Jane" />
</div>
<div>
<label htmlFor="lastName">Last Name</label>
<Field id="lastName" name="lastName" placeholder="Doe" />
</div>
<div>
<label htmlFor="email">Email</label>
<Field
id="email"
name="email"
placeholder="jane@acme.com"
type="email"
/>
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
) : (
<Formik
key="2"
initialValues={{
fn: "",
ln: ""
}}
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
alert(JSON.stringify(values, null, 2));
}}
>
<Form>
<div>
<label htmlFor="fn">F N</label>
<Field id="fn" name="fn" placeholder="Jane" />
</div>
<div>
<label htmlFor="ln">L N</label>
<Field id="ln" name="ln" placeholder="Doe" />
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
)}
</div>
);
}