我声明了一个名为EditLinksModal
的父组件,该组件使用了useState
钩子。它具有状态属性hasError
,它是一个JS对象,其字段传递到多个URLField子组件。
但是,孩子似乎没有得到更新的道具。实际上,即使我正在调用setHasError
,似乎也没有发生重新渲染,因为子级中的任何console.log
语句都不会打印任何内容。
我下面有3条console.log
语句。父级(console.log
)中的2条EditLinksModal
语句正在打印正确的最新状态属性。但是,子级中的console.log
甚至不会执行。我在做什么错了?
这是因为我将useState
与JS对象的本地状态属性结合使用(即hasError
是一个对象,但不是真正嵌套的对象)。即便如此,我还是感到困惑,为什么正确地更新了hasError
状态属性,但是子组件却没有更新其error
属性。
const URLField = ({label, name, placeholder, value, onHandleChange, error, errorText}) => {
console.log(error) // problem: not even executing or printing anything
return (
<>
<Header5>{label}</Header5>
<CustomInput
name={name}
placeholder={placeholder}
variant="text"
value={value}
onChange={(evt) => onHandleChange(name, evt.target.value)}
/>
{error && <SystemComponent color={theme.colors.alertAction}>{errorText}</SystemComponent>}
</>
)
}
const EditLinksModal = ({visible, handleCloseModal}) => {
const [hasError, setHasError] = useState({
facebookUrl: false,
linkedInUrl: false,
githubUrl: false,
websiteUrl: false
});
const validateUrl = (errorList, fieldName, fieldValue, allowedHostsList = false) => {
// .........
}
const handleSave = (evt) => {
evt.preventDefault();
const errors = hasError;
validateUrl(errors, 'facebookUrl', formValues['facebookUrl'], ['facebook.com']);
validateUrl(errors, 'githubUrl', formValues['githubUrl'], ['github.com']);
validateUrl(errors, 'linkedInUrl', formValues['linkedInUrl'], ['linkedin.com']);
validateUrl(errors, 'websiteUrl', formValues['websiteUrl']);
console.log(errors); // this prints correct, up-to-date values
setHasError(errors);
}
console.log(hasError); // this prints correct, up-to-date values
return (
<SystemComponent>
<URLField
label="Facebook"
name="facebookUrl"
placeholder="Search"
value={formValues["facebookUrl"]}
error={hasError.facebookUrl}
errorText={"Please Enter Valid Facebook Profile Url."}
onHandleChange={handleChange}
/>
</SystemComponent>
)
答案 0 :(得分:1)
您的问题是状态对象errors
具有相同的引用,因此setHasError
无法更新状态。如果要使同一对象errors
发生突变,请使用传播运算符创建具有相同属性的新对象:
const handleSave = (evt) => {
evt.preventDefault();
const errors = hasError;
validateUrl(errors, 'facebookUrl', formValues['facebookUrl'], ['facebook.com']);
validateUrl(errors, 'githubUrl', formValues['githubUrl'], ['github.com']);
validateUrl(errors, 'linkedInUrl', formValues['linkedInUrl'], ['linkedin.com']);
validateUrl(errors, 'websiteUrl', formValues['websiteUrl']);
console.log(errors); // this prints correct, up-to-date values
// Use spread operator to create a new object
setHasError({ ...errors });
}