如何在Formik中为TextField设置带条件的值?
解决方案:实现选择名称后自动填充Formik TextField
要实现选择名称后自动填充到Formik绑定的TextField,核心是修改Formik对应字段的值,以下是几种可行的实现方式:
1. 使用Formik的setFieldValue方法(最常用)
通过Formik提供的setFieldValue方法直接设置指定字段的值,TextField会自动同步更新。
方式一:通过Formik的render props获取setFieldValue
修改你的Dashboard组件中Formik的结构,在内部通过render props拿到setFieldValue,然后在选择名称的操作中调用它:
<Formik enableReinitialize={true} initialValues={{ ...initialFormState }} validationSchema={formValidation} onSubmit={(values, { resetForm }) => { console.log(values); valueSheet.postSheet(); setShow(false); resetForm({ values: '' }); setTimeout(() => { window.location.reload(false); }, 2000); }} > {/* 通过render props获取setFieldValue */} {({ setFieldValue }) => ( <Form> <div> {/* 示例:假设这是选择名称的按钮组,点击后填充值 */} <div style={{ marginBottom: 16 }}> <button onClick={() => setFieldValue('sheetNo', '销售统计表')}>选择销售统计表</button> <button onClick={() => setFieldValue('sheetNo', '用户信息表')} style={{ marginLeft: 8 }}>选择用户信息表</button> </div> <TextfieldWrapper name='sheetNo' label="New Sheet Name" {/* 移除多余的inputRef,Formik已自动绑定控件 */} /> </div> </Form> )} </Formik>
方式二:在独立选择组件中使用useFormikContext
如果你的名称选择逻辑是独立组件,可以用useFormikContext钩子获取Formik的上下文方法:
// 新建名称选择组件 import React from 'react'; import { useFormikContext } from 'formik'; const SheetNameSelector = () => { const { setFieldValue } = useFormikContext(); const handleSelect = (sheetName) => { // 设置sheetNo字段的值 setFieldValue('sheetNo', sheetName); }; return ( <div style={{ marginBottom: 16 }}> <button onClick={() => handleSelect('月度报表')}>月度报表</button> <button onClick={() => handleSelect('季度汇总表')} style={{ marginLeft: 8 }}>季度汇总表</button> </div> ); }; export default SheetNameSelector;
然后在Dashboard的Form中引入该组件:
<Form> <div> <SheetNameSelector /> <TextfieldWrapper name='sheetNo' label="New Sheet Name" /> </div> </Form>
2. 通过更新initialValues结合enableReinitialize实现
如果你是通过外部状态管理选中的名称,可以更新initialValues并利用enableReinitialize={true}让Formik自动同步值:
// 在Dashboard组件中定义状态保存选中的名称 const [selectedSheetName, setSelectedSheetName] = useState(''); // 选择名称时更新状态 const handleSelectName = (name) => { setSelectedSheetName(name); }; // 传递给Formik的initialValues包含选中的名称 <Formik enableReinitialize={true} initialValues={{ ...initialFormState, sheetNo: selectedSheetName }} validationSchema={formValidation} onSubmit={(values, { resetForm }) => { // 原有提交逻辑 }} > <Form> <div> <button onClick={() => handleSelectName('年度总表')}>选择年度总表</button> <TextfieldWrapper name='sheetNo' label="New Sheet Name" /> </div> </Form> </Formik>
额外修正:修复TextfieldWrapper中的拼写错误
你的TextfieldWrapper里把meta拼成了mata,会导致错误提示逻辑失效,需要修正:
import React from 'react'; import TextField from '@mui/material/TextField' import { useField } from 'formik'; const TextfieldWrapper = ({ name, ...otherProps }) => { // 修正拼写:mata → meta const [field, meta, helpers] = useField(name); const configTextfield = { ...field, ...otherProps, fullWidth: true, variant: 'outlined', margin: "normal", size: 'small' }; // 修正meta的引用 if (meta && meta.touched && meta.error) { configTextfield.error = true; configTextfield.helperText = meta.error; } return ( <TextField sx={{ "& .MuiInputBase-root": { height: 45 } }} {...configTextfield} /> ); }; export default TextfieldWrapper;
内容的提问来源于stack exchange,提问作者Humail Saleem
相关产品推荐
相关产品推荐

