[英]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.