如何从 From 外部更改 Formik TextField 值?
Posted
技术标签:
【中文标题】如何从 From 外部更改 Formik TextField 值?【英文标题】:How do I change a Formik TextField value from the outside of the From? 【发布时间】:2020-08-01 13:45:22 【问题描述】:在模块对话框中,我想更改输入值 (#quaggaIsbn) 的值。我试过document.getElementById("quaggaIsbn").value = result.codeResult.code
,但它没有反映到表单发送到服务器的值上。如何更改 Formik 发送到服务器的值?
NewProjectDialog.js
import React from 'react';
import PropTypes from 'prop-types'
import Formik, Field, Form from 'formik'
import TextField from 'formik-material-ui'
import makeStyles from '@material-ui/core/styles'
import Button from '@material-ui/core/Button'
import Dialog from '@material-ui/core/Dialog'
import DialogTitle from '@material-ui/core/DialogTitle'
import DialogActions from '@material-ui/core/DialogActions'
import DialogContent from '@material-ui/core/DialogContent'
import styles from './NewProjectDialog.styles'
import Quagga from 'quagga';
const useStyles = makeStyles(styles)
function NewProjectDialog( onSubmit, open, onRequestClose )
const classes = useStyles()
function handleSubmit(values, setSubmitting )
return onSubmit(values).then(() =>
setSubmitting(false)
)
function inputFile()
const file = document.getElementById("quaggaFile").files[0];
const reader = new FileReader();
reader.addEventListener("load", function ()
// convert image file to base64 string
analyzeQuaggaFile(reader.result);
//preview.src = reader.result;
, false);
reader.readAsDataURL(file);
function analyzeQuaggaFile(src)
Quagga.decodeSingle(
// src: "/image-002.jpg",
src: src,
numOfWorkers: 0, // Needs to be 0 when used within node
inputStream:
size: 800 // restrict input-size to be 800px in width (long-side)
,
decoder:
readers: ["ean_reader"] // List of active readers
,
, function(result)
if(result.codeResult)
console.log("result", result.codeResult.code);
document.getElementById("quaggaIsbn").value = result.codeResult.code ;
else
console.log("not detected");
);
return (
<Dialog open=open onClose=onRequestClose>
<DialogTitle id="new-project-dialog-title">Sell book</DialogTitle>
<Formik initialValues= name: '' onSubmit=handleSubmit>
( errors, isSubmitting ) => (
<Form className=classes.root>
<DialogContent>
<Field
id="quaggaIsbn"
name="isbn"
label="ISBN"
component=TextField
margin="normal"
fullWidth
/>
Scan bar code:<input id="quaggaFile" type="file" accept="image/*" capture="camera" onChange=inputFile/>
<Field
name="title"
label="Title"
component=TextField
margin="normal"
fullWidth
/>
<Field
name="status"
label="Status"
component=TextField
margin="normal"
fullWidth
/>
<Field
name="price"
label="Price"
component=TextField
margin="normal"
fullWidth
/>
Book cover:<input id="image" type="file"/>
</DialogContent>
<DialogActions>
<Button onClick=onRequestClose color="secondary">
Cancel
</Button>
<Button type="submit" color="primary" disabled=isSubmitting>
isSubmitting ? 'Creating...' : 'Create'
</Button>
</DialogActions>
</Form>
)
</Formik>
</Dialog>
)
NewProjectDialog.propTypes =
onSubmit: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
onRequestClose: PropTypes.func.isRequired
export default NewProjectDialog
【问题讨论】:
您想设置默认值还是应该何时更改该值? 当我选择一个文件并加载到#quaggaFile 时,我想更改#quaggaIsbn 的值。 (它反映到视图而不是表单信息,当我提交表单时,它不会发送到服务器。) 当我上传文件时,会调用 inputFile()。调用analyzeQuaggaFile() 和analyzeQuaggaFile() 尝试更改表单值#quaggaIsbn,但似乎没有因为#quaggaIsbn 的值未包含在提交的数据中。 【参考方案1】:一旦使用 enableReinitialize 属性在其上下文之外更新其属性,就可以重置整个 Formik。
https://formik.org/docs/api/formik#enablereinitialize-boolean
像这样:
<Formik validationSchema=validationSchema initialValues=this.state.formValues onSubmit=this.handleFormSubmission enableReinitialize=true>
【讨论】:
【参考方案2】:Formik 渲染方法提供了一个使用 setFieldValue
手动更改字段值的道具,它将字段名称和新值作为参数,您可以从 here 了解更多信息
至于你需要改变的是这里
// accept a new parameter which you can pass to the `analyzeQuaggaFile` function
function inputFile(setFieldValue)
const file = document.getElementById("quaggaFile").files[0];
const reader = new FileReader();
reader.addEventListener(
"load",
function ()
// pass the setFieldValue
analyzeQuaggaFile(reader.result, setFieldValue);
,
false
);
reader.readAsDataURL(file);
// second parameter is setFieldValue
function analyzeQuaggaFile(src, setFieldValue)
Quagga.decodeSingle(
src: src,
numOfWorkers: 0,
inputStream:
size: 800,
,
decoder:
readers: ["ean_reader"],
,
,
function (result)
if (result.codeResult)
// update the isbn field value
setFieldValue("isbn", result.codeResult.code);
else
console.log("not detected");
);
现在在你的 JSX 代码中改变这个:
<Formik initialValues= name: "" onSubmit=handleSubmit>
( errors, isSubmitting, setFieldValue ) => (
<Form className=classes.root>
/* Other fields */
Scan bar code:
<input
id="quaggaFile"
type="file"
accept="image/*"
capture="camera"
onChange=() => inputFile(setFieldValue) // pass the setFieldValue property from formik
/>
/* Other fields */
</Form>
)
</Formik>;
【讨论】:
太棒了!谢谢!!【参考方案3】: import
useFormik
from "formik";
import * as yup from 'yup';
export default function ChangeFormikValueOutsideForm()
const initialValues =
first_name: 'John',
last_name: 'Doe'
const validationSchema = yup.object(
first_name: yup.string("must be a string")
.required("Must have a first name"),
last_name: yup.string("must be a string")
)
const formik = useFormik(
initialValues,
validationSchema,
onSubmit: (values) =>
)
let handleLastNameChange = () =>
formik.setFieldValue('last_name', Math.ceil(Math.random() * 100))
return (
<form onSubmit =
formik.handleSubmit
>
<p> First Name * </p>
<input
name = "first_name"
id = "first_name"
type = "text"
onChange =
formik.handleChange
value =
formik.values.first_name
/>
<p> Last Name </p>
<input
name = "last_name"
id = "last_name"
type = "text"
onChange =
handleLastNameChange
value =
formik.values.last_name
/>
<input
type = "submit"
value = "Submit Form"
/>
</form>
)
它与 useFormik 钩子一起工作,这允许您在 formik 标记之外定义表单,然后从 formik 变量中受益,以在表单之外执行 setFieldValue 方法。事实上,您正在处理的表格完全脱离了表格;)
与材质 ui 一起使用的想法也相同。它有效
【讨论】:
以上是关于如何从 From 外部更改 Formik TextField 值?的主要内容,如果未能解决你的问题,请参考以下文章
当我提交表单并尝试更改值时,Formik + Material UI 错误
React Formik Material UI Autocomplete:如何从 localStorage 填充自动完成内部的值?
如何使用 Formik 在 react-datepicker 中设置初始日期?