繁体   English   中英

Formik 初始值与 Redux 不同步

[英]Formik Initial Values out of Sync with Redux

此表单用于编辑用户配置文件。 它应该为初始值加载最新的用户数据。 为了处理这个问题,我在 useEffect 中添加了一个 redux fetchUser 操作,并将表单的初始值设置为 redux 存储中的 currentUser。 fetchUser 命中数据库端点并更新 redux 存储中的 currentUser。

但是,如果我提交表单并重新加载页面,则初始数据不会更新。

我不确定为什么我的初始值/表格不是我的 redux 商店的最新信息。 如果我离开它并导航回它两次,该表单将更新为正确的数据。

我的假设是每次渲染组件时表单都不会重置初始值。 看起来数据是持久的。 我尝试将 object 传递给 resetForm() 以强制更新初始值,但这会导致同样的问题。 如果

这是完整的反应组件:


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 component 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> components */}
              <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)

enableReinitialize={true}作为 Formik 属性。 所以这:

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

@Jared 通过使用enableReinitialize:true钩子回答对我有用

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

您可能需要将您的useEffect挂钩分成 2 个useEffect “componentDidMount”循环的一个钩子(例如[] )和另一个监视currentUser的变化。

例子:

const [formData, setFormData] = useState(null)

useEffect(() => {
  //grab user on component 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 ])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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