父级状态更改后,子级组件道具未更新

时间:2020-02-22 21:26:29

标签: javascript reactjs

我声明了一个名为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>
    )

1 个答案:

答案 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 });
}