简体   繁体   中英

React useState() - how to update objects

I can't seem to update my state with useState(), whenever my alert displays, I always see my state displaying its initial value.

Sample code below, my expectation is that when I click the Save button, setData will update data with new values I have in my form, then display contents of data with alert. However, what's happening is that whenever I click Save, alert is always displaying my initial values.

How do I update data with my field values so that my alert can pick up the changes?

const initialValues = {
    title: "",
    description: ""
}

const CreateForm = (props) => {
    const [data, setData] = useState(initialValues);

    const handleSave = (values) => {
        setData({
            title: values.title,
            description: values.description
        });

        setTimeout(() => {
            alert(JSON.stringify(data, null, 2));
        }, 3000)
    }
    return (
        <div>
             <Formik initialValues={data}
                validationSchema={validationSchema}
                onSubmit={(values) => {
                    setTimeout(() => {
                        alert(JSON.stringify(values, null, 2));
                    }, 3000)
                }}
            >
                {props => (
                    <Form>
                        <TextField name="title" type="input" label="Title" />
                        <TextField name="description" type="input" label="description" />

                        <div >
                            <Button type="submit" variant="contained" color="primary">Submit</Button>&nbsp;
                            <Button variant="contained" color="secondary" onClick={() => handleSave(props.values)}>Save</Button>&nbsp;
                        </div>
                    </Form>
                )}
            </Formik>
        </div>
    )

}

export default CreateForm

you can use "useEffect" hook, what it will do basically is it will see if there are any changes in the data, which we have passed as source to useEffect, if there are changes it will trigger the function passed to it, where you can alert the data, As in your code in function "handleSave" we are assigning new value to data, which will eventually trigger the useEffect.

  useEffect(() => {
         //logic for the alert
         alert(JSON.stringify(data, null, 2));
  },[data]);

Assuming that values also did not update, try switching to Formik's Field object instead of TextField.

<Form>
  <Field name="title" type="input" label="Title" />
  <Field name="description" type="input" label="description" />

  <div >
    <Button type="submit" variant="contained" color="primary">Submit</Button>&nbsp;
    <Button variant="contained" color="secondary" onClick={() => handleSave(props.values)}>Save</Button>&nbsp;
  </div>
</Form>

If TextField is a third-party control, then you may have to update the code like this:

<Field name="title" type="input" label="Title" component={TextField}/>

You sometimes need a bindings library to map all the formik functionality back to a third-party lib. Like you may use formik-material-ui to provide the bindings for Material-UI.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM