简体   繁体   English

父状态更改后子组件道具不会更新

[英]Child component props not updating after parent's state changes

I declared a parent component called EditLinksModal that uses the useState hook.我声明了一个名为EditLinksModal的父组件,它使用useState钩子。 It has a state property hasError , which is a JS object whose fields are passed to multiple URLField child components.它有一个 state 属性hasError ,它是一个 JS 对象,其字段被传递给多个 URLField 子组件。

However, the child does not seem to be getting the updated props.然而,孩子似乎没有得到更新的道具。 In fact, it seems that re-rendering isn't happening even though I am calling setHasError since any console.log statements in the child don't print anything.事实上,即使我调用setHasError似乎也没有发生重新渲染,因为孩子中的任何console.log语句都不打印任何内容。

I have 3 console.log statements below.我在下面有 3 个console.log语句。 The 2 console.log statements in the parent ( EditLinksModal ) are printing the correct and up-to-date state properties.父级 ( EditLinksModal ) 中的 2 个console.log语句正在打印正确且最新的状态属性。 However, the console.log in the child does not even execute.但是,子console.log中的console.log甚至不执行。 What am I doing wrong ?我究竟做错了什么 ?

Is this because I am using useState in combination with a local state property that is a JS Object (ie. hasError is an object, but not a really deeply-nested one).这是因为我将useState与作为 JS 对象的本地状态属性结合使用(即hasError是一个对象,但不是真正嵌套的对象)。 Even so, I am puzzled why the hasError state property is properly updated, but the child-component doesn't have its error prop updated.即便如此,我还是不明白为什么正确更新了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>
    )

Your problem is that the state object errors has the same reference, thus setHasError does not update the state.您的问题是状态对象errors具有相同的引用,因此setHasError不会更新状态。 If you want to mutate that same object errors , then use spread operator to create a new object with the same properties:如果你想改变相同的对象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 });
}

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

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