最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Formik Initial Values out of Sync with Redux - Stack Overflow

programmeradmin0浏览0评论

This form is used to edit a user profile. It should load with up to date user data for the initial values. To handle this, I've added a redux fetchUser action in useEffect and set the initial values of the form to the currentUser in the redux store. fetchUser hits a database endpoint and updates the currentUser in the redux store.

However, if I submit the form and reload the page, the initial data is not updated.

I'm not sure why my initial values/form is not up to date with my redux store. The form will update with the right data if I navigate away from it and navigate back to it twice.

My assumption is that the form is not resetting the initial value each time the ponent is rendering. It looks like that data is persisting. I have tried passing in an object to resetForm() to force the initial values to update, but this results in the same issue. If

Here is the full react ponent:


import { Formik, Form, Field, ErrorMessage } from "formik"
//redux action that fetches current user
import { fetchUser } from "../../actions"
import { connect } from "react-redux"
import profileSchema from "./yupSchema"
import updateProfile from "./updateAxiosCall"

const submitData = (data, resetForm, tagNames) => {
  const newProfile = { ...data}
  //end point call - working as intended
  updateProfile(newProfile)
  resetForm()
}

const ProfileForm = ({ currentUser, fetchUser }) => {


  const [formData, setFormData] = useState(null)
  useEffect(() => {
    //grab user on ponent render
    fetchUser()
    setFormData({
      linkedin: currentUser.linkedin,
      github: currentUser.github,
      instagram: currentUser.instagram,
      facebook: currentUser.facebook,
      twitter: currentUser.twitter,
      header: currentUser.header,
      bio: currentUser.bio,
    })
  }, [])


  if (formData === null) {
    return <div>Not ready</div>
  } else {
    return (
        <Formik
          initialValues={formData}
          validationSchema={profileSchema}
          onSubmit={(values, { resetForm }) => {
            submitData(values, resetForm, tagNames)
          }}
        >
          {({ errors, resetForm, handleChange, touched, values, onSubmit }) => (
            <Form
              style={{
                display: "flex",
                flexDirection: "column",
                width: "100%",
              }}
              autoComplete="off"
            >
              //This is up to date
              <h1>{currentUser.header}</h1>
              <TextField
                error={errors.header && touched.header}
                onChange={handleChange}
                name="header"
                variant="outlined"
                value={values.header || ""}
                id="header"
                margin="normal"
                label="header"
                helperText={
                  errors.header && touched.header ? errors.header : null
                }
              />

         {/* ...additional <TextField> ponents */}
              <Button
                style={{ margin: "10px 0px" }}
                size="large"
                margin="normal"
                type="submit"
                variant="contained"
                color="primary"
              >
                Save
              </Button>
            </Form>
          )}
        </Formik>

    )
  }
}

function mapStateToProps(state) {
  return {
    currentUser: state.currentUser,
  }
}

export default connect(mapStateToProps, { fetchUser })(ProfileForm)

This form is used to edit a user profile. It should load with up to date user data for the initial values. To handle this, I've added a redux fetchUser action in useEffect and set the initial values of the form to the currentUser in the redux store. fetchUser hits a database endpoint and updates the currentUser in the redux store.

However, if I submit the form and reload the page, the initial data is not updated.

I'm not sure why my initial values/form is not up to date with my redux store. The form will update with the right data if I navigate away from it and navigate back to it twice.

My assumption is that the form is not resetting the initial value each time the ponent is rendering. It looks like that data is persisting. I have tried passing in an object to resetForm() to force the initial values to update, but this results in the same issue. If

Here is the full react ponent:


import { Formik, Form, Field, ErrorMessage } from "formik"
//redux action that fetches current user
import { fetchUser } from "../../actions"
import { connect } from "react-redux"
import profileSchema from "./yupSchema"
import updateProfile from "./updateAxiosCall"

const submitData = (data, resetForm, tagNames) => {
  const newProfile = { ...data}
  //end point call - working as intended
  updateProfile(newProfile)
  resetForm()
}

const ProfileForm = ({ currentUser, fetchUser }) => {


  const [formData, setFormData] = useState(null)
  useEffect(() => {
    //grab user on ponent render
    fetchUser()
    setFormData({
      linkedin: currentUser.linkedin,
      github: currentUser.github,
      instagram: currentUser.instagram,
      facebook: currentUser.facebook,
      twitter: currentUser.twitter,
      header: currentUser.header,
      bio: currentUser.bio,
    })
  }, [])


  if (formData === null) {
    return <div>Not ready</div>
  } else {
    return (
        <Formik
          initialValues={formData}
          validationSchema={profileSchema}
          onSubmit={(values, { resetForm }) => {
            submitData(values, resetForm, tagNames)
          }}
        >
          {({ errors, resetForm, handleChange, touched, values, onSubmit }) => (
            <Form
              style={{
                display: "flex",
                flexDirection: "column",
                width: "100%",
              }}
              autoComplete="off"
            >
              //This is up to date
              <h1>{currentUser.header}</h1>
              <TextField
                error={errors.header && touched.header}
                onChange={handleChange}
                name="header"
                variant="outlined"
                value={values.header || ""}
                id="header"
                margin="normal"
                label="header"
                helperText={
                  errors.header && touched.header ? errors.header : null
                }
              />

         {/* ...additional <TextField> ponents */}
              <Button
                style={{ margin: "10px 0px" }}
                size="large"
                margin="normal"
                type="submit"
                variant="contained"
                color="primary"
              >
                Save
              </Button>
            </Form>
          )}
        </Formik>

    )
  }
}

function mapStateToProps(state) {
  return {
    currentUser: state.currentUser,
  }
}

export default connect(mapStateToProps, { fetchUser })(ProfileForm)
Share Improve this question asked Jun 14, 2020 at 19:15 WriterStateWriterState 3694 silver badges20 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 11

put enableReinitialize={true} as a Formik property. so this:

<Formik
enableReinitialize={true}
initialValues={formData}
...

@Jared answer works for me by using enableReinitialize:true hook

const formik = useFormik({
    initialValues: {
        title: "",
        text: "",
        authorid: `${user.id}`,
        cat_id: '1',
    },
    validateOnBlur: true,
    onSubmit,
    enableReinitialize: true,
});

You might need to separate your useEffect hook into 2 useEffects. One hook for the "ponentDidMount" cycle (e.g. []) and another watching changes to currentUser.

Example:

const [formData, setFormData] = useState(null)

useEffect(() => {
  //grab user on ponent render
  fetchUser()
}, [])


useEffect(() => {
  setFormData({
    linkedin: currentUser.linkedin,
    github: currentUser.github,
    instagram: currentUser.instagram,
    facebook: currentUser.facebook,
    twitter: currentUser.twitter,
    header: currentUser.header,
    bio: currentUser.bio,
  })
}, [ currentUser ])
发布评论

评论列表(0)

  1. 暂无评论