我正在为父/子组件使用React钩子.

现在,我的父组件(companyIcon)中有状态,我需要根据子组件中的一些验证来更新它.我将validationCallback作为回调函数传递给子组件,并根据从子组件获得的值更新父状态.

现在的问题是在我更新父状态后,我的子组件中的状态值被重置.请帮助我在下面的实现中做错了什么?

function ParentComp(props) {
    const [companyIcon, setCompanyIcon] = useState({ name: "icon", value: '' });

    const validationCallback = useCallback((tabId, hasError) => {
        if (hasError) {
            setCompanyIcon(prevItem => ({ ...prevItem, value: 'error'}));
// AFTER ABOVE LINE IS EXECUTED, my Child component state "myAddress" is lost i.e. it seems to reset back to empty value.
        }
    }, []);
    

    const MyChildCmp = (props) => { 
        const [myAddress, setmyAddress] = useState('');

        useEffect(() => {
                if (myAddressExceptions.length > 0) {
                    props.validationCallback('MyInfo', true);
                } else {
                    props.validationCallback('MyInfo', false);
                }
            }, [myAddressExceptions])

    
        const handlemyAddressChange = (event) => {        
            //setmyAddress(event.target.value);
            //setmyAddressExceptions(event.target.value);
            console.log(myAddressExceptions);
        }

        return (
            <>
                <div className="row" style={{ display: 'flex', flexDirection: 'row', width: '1000px'}}>
                        <div style={{ width: '20%'}}>
                            <FormField 
                                label='Company Address' 
                                required
                                helperText={mergedErrorMessages(myAddressExceptions)}
                                validationState={
                                    myAddressExceptions[0] ? myAddressExceptions[0].type : ''
                                }
                            >
                                <Input id='myAddress'
                                    value={myAddress}
                                    //onChange={handlemyAddressChange}
                                    onChange={({ target: { value } }) => {
                                        validateInputValue(value);
                                    }}
                                    onBlur={handleBlur}
                                    inputProps={{maxLength: 9}} />
                            </FormField>
                        </div>
                </div>
            </>
        ); 
    }

    return (
        <div className="mainBlock">
            Parent : {companyIcon}
            {displayMyChild && <MyChildCmp validationCallback={validationCallback}/>}
        </div>
    )
}

export default withRouter(ParentComp);

推荐答案

以下是您可能在child中失go 状态的一些原因(可能还有更多原因,但这些最适用于您):

    {displayMyChild && <MyChildCmp validationCallback={validationCallback}/>}

这里,如果在一个点displayMyChild是真实的,那么是falsy,这意味着组件MyChildCmp将得到unmounted,因此其所有状态都将消失.

但是现在,即使你没有那个条件,并且始终渲染MyChildCmp,你仍然会遇到类似的问题,这是因为你定义了MyChildCmp inside另一个组件.当您这样做时,在父组件的每个渲染上,会重新创建函数MyChildCmp,并且react的reconciliation算法认为您在下一个渲染中渲染了different component type,因此它会 destruct 组件实例.将该组件的定义移到父组件之外.

Javascript相关问答推荐

无法在page. evalve()内部使用外部函数

如何让\w token 在此RegEx中表现得不贪婪?

为什么在集内和集外会产生不同的promise 状态(使用Promise.race)?

微软Edge Select 间隙鼠标退出问题

我应该在redux reducer中调用其他reducer函数吗?

Cypress -使用commands.js将数据测试id串在一起失败,但在将它们串在一起时不使用命令有效

Rehype将hashtag呈现为URL

TypeScript索引签名模板限制

当点击注册页面上的注册按钮时,邮箱重复

Regex结果包含额外的match/group,只带一个返回

如何在JavaScript文件中使用Json文件

保持物品顺序的可变大小物品分配到平衡组的算法

更新动态数据中对象或数组中的所有值字符串

Web Crypto API解密失败,RSA-OAEP

如何将数组用作复合函数参数?

如何防止ionic 输入中的特殊字符.?

Phaserjs-创建带有层纹理的精灵层以自定义外观

每隔3个项目交替显示,然后每1个项目交替显示

使用可配置项目创建网格

在HTML5画布上下文中使用putImageData时,重载解析失败