reactjs - 状态挂钩不会在 redux 存储更新时更新状态参数
问题描述
我有并更新用户页面。存在一种基于功能组件的简单形式。我使用钩子来处理状态和输入参数。默认参数(可以更改)我从 redux 商店获得(我在 useEffect 中获取它们)。页面加载存储更改后,机器人挂钩不会更新表单中的必要属性,并且有空输入。我怎么能假设,在 store update hookk 之后会更新状态,但没有。我怎么解决这个问题?
零件:
const EditUserPage: React.FunctionComponent<Props> = () => {
const dispatch = useDispatch();
const history = useHistory();
const {profileId} = useParams<UrlParams>();
useEffect(() => {
dispatch(getRolesList());
console.log("URL PARAM=", profileId)
dispatch(getProfileById(parseInt(profileId)));
}, []);
const isEmailDuplicated: boolean = useSelector(getEmailDuplicated);
const rolesList: Array<PlainObject> = useSelector(userRolesList);
const contetType: string = useSelector(adminContentType);
const userProfileData: PlainObject = useSelector(selectedUserProfile);
const [startDate, setStartDate] = useState<Date>(new Date());
const [firstName, setFirstName] = useState<string>(userProfileData.firstName);
const [lastName, setLastName] = useState<string>(userProfileData.lastName ? userProfileData.lastName : "");
const [role, setRole] = useState<string>(userProfileData.user && userProfileData.user.roles[0].name);
const [gender, setGender] = useState<string>(userProfileData.gender ? userProfileData.gender : "");
const [address, setAddress] = useState<string>(userProfileData.address ? userProfileData.address : "");
const [phone, setPhone] = useState<string>(userProfileData.telephone ? userProfileData.telephone : "");
const [office, setOffice] = useState<string>(userProfileData.office ? userProfileData.office : "");
const [socialNumber, setSocialNumber] = useState<string>(userProfileData.socialNumber ? userProfileData.socialNumber : "");
const [about, setAbout] = useState<string>(userProfileData.about ? userProfileData.about : "");
const [login, setLogin] = useState<string>(userProfileData.email ? userProfileData.email : "");
const roleDropdownOptions = rolesList && rolesList.map((role) => {
console.log("?????",userProfileData)
return {
key: role.id,
text: role.name.toLowerCase(),
value: role.name,
}
})
//validate email
const mailRegex = new RegExp(/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/g);
const isMailValid = login && mailRegex.test(login);
//validate phone number
const phoneRegex = new RegExp(/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s./0-9]*$/g)
const isPhoneValid = phone && phoneRegex.test(phone);
const handleSubmit = (event: { preventDefault: () => void; }) => {
const dateFormat = require("dateformat");
event.preventDefault();
userProfileData["firstName"] = firstName;
userProfileData["lastName"] = lastName;
userProfileData["email"] = login;
userProfileData["telephone"] = phone;
userProfileData["about"] = about;
userProfileData["office"] = office;
userProfileData["address"] = address;
userProfileData["socialNumber"] = socialNumber;
userProfileData["dateOfBirth"] = dateFormat(startDate, "yyyy-mm-dd");
userProfileData["gender"] = gender;
const promise = new Promise(() => {
return dispatch(updateProfile(userProfileData));
})
promise
.then(() => history.push("/admin"))
.then(() => {
if (contetType === adminContentTypes.PERSONAL) {
dispatch(getPersonalProfiles());
} else {
dispatch(getPatientProfiles());
}
})
}
return (
<Fragment>
<Header as="h1">
EDIT USER
</Header>
<Divider/>
<Form onSubmit={handleSubmit}>
{
isEmailDuplicated &&
<Message
negative={true}
header="Account already exists"
content="An account already exists for this email address, please log in or confirm your email address is correct"
/>
}
<Form.Group widths="equal">
<Form.Input
label="First name"
name="firstName"
value={firstName}
required={true}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setFirstName(e.target.value)}
/>
<Form.Input
label="Last name"
name="lastName"
value={lastName}
required={true}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setLastName(e.target.value)}
/>
<Form.Input
label="Email"
name="login"
required={true}
value={login}
error={!isMailValid && login ? {
content: "Please enter a valid email address",
pointing: "below",
} : false}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setLogin(e.target.value)}
/>
</Form.Group>
<Divider hidden/>
<Form.Group>
<Form.Select
width={4}
placeholder="User role"
label="User role"
name="user_role"
selection
options={roleDropdownOptions}
value={role}
required={true}
onChange={(event: React.ChangeEvent<HTMLSelectElement>, data: PlainObject) => {
event.preventDefault();
setRole(data.value);
}}
/>
<Form.Select
width={4}
value={gender}
label="Gender"
name="gender"
selection
options={options}
required={true}
onChange={(event: React.ChangeEvent<HTMLSelectElement>, data: PlainObject) => setGender(data.value)}
/>
<Form.Input
width={4}
label="Office"
name="office"
value={office}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setOffice(e.target.value)}
/>
<div style={{"paddingLeft": "7px", "paddingRight": "7px"}}>
<label>
Date of birth
</label>
<br/>
<DatePicker
selected={startDate}
onChange={(date: Date) => {
setStartDate(date)
}}
peekNextMonth
showMonthDropdown
showYearDropdown
dropdownMode="select"
/>
</div>
</Form.Group>
<Divider hidden/>
<Form.Group>
<Form.Input
width={4}
label="Address"
name="address"
value={address}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setAddress(e.target.value)}
/>
<Form.Input
width={4}
label="Phone number"
name="telephone"
value={phone}
required={true}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setPhone(e.target.value)}
error={!isPhoneValid && phone ? {
content: "Please enter a valid phone number",
pointing: "below",
} : false}
/>
<Form.TextArea
label="About"
value={about}
width={8}
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>, data: PlainObject) => setAbout(data.value)}
/>
</Form.Group>
<Divider hidden/>
<Form.Group widths="equal">
<Form.Input
label="Social number"
name="socialNumber"
value={socialNumber}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSocialNumber(e.target.value)}
/>
</Form.Group>
<Divider hidden/>
<Button
floated="right"
size="medium"
onClick={() => history.push("/admin")}
>
Back
</Button>
<Button
color="blue"
floated="right"
size="medium"
disabled={!isMailValid || !isPhoneValid}
>
Save
</Button>
</Form>
</Fragment>
);
}
export default EditUserPage;
解决方案
我想你会想要另一个useEffect
监视变化的userProfileData
。
现在,您正在使用 初始化所有钩子状态变量userProfileData
,但在第一次传递时,数据为空。
当商店更新时,userProfileData
值应该会改变,但是这个组件没有设置为对它做任何事情。
const [firstName, setFirstName] = useState<string>(userProfileData.firstName);
如果您在下面还有一个调用set
回调的钩子,它应该在商店完成后更新。
useEffect(() => {
setFirstName(userProfileData.firstName);
}, [userProfileData])'
如果您遇到以下情况,这可能会导致问题
- 用户已输入信息
- 商店更新
如果该实例是可能的,您可以在该字段的开头添加逻辑useEffect
以不更新该字段(如果该字段已更新)。
推荐阅读
- javascript - 你如何捕捉流转换错误?
- shell - Shell - cURL 请求之间的延迟
- javascript - Chrome 扩展程序 - 如何定期访问网络摄像头和音频?
- linux - Spring Boot 应用程序无法读取环境属性
- apollo-server - 在阿波罗响应中添加来自服务器的消息(Nodejs)
- ruby-on-rails - Rails,生产环境中的 Apartment gem,错误消息:未找到租户
- php - cURL 请求在本地主机上不起作用并且没有错误
- ios - 从 Firebase 加载图像时,集合视图单元格顺序发生变化
- javascript - 打印区域在打印 js 中无法正常工作
- java - 删除每个出现超过“N”次问题的元素