簡體   English   中英

父組件重新渲染后 React 子組件狀態丟失

[英]React child component state is lost after parent component re-renders

我正在為父/子組件使用 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);

以下是您可能會失去兒童狀態的一些原因(可能還有更多,但這些最適用於您):

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

在這里,如果在某一時刻displayMyChild為真, MyChildCmp falsy卸載,因此它的所有狀態都將消失。

但是現在,即使您沒有該條件並始終呈現MyChildCmp ,您仍然會遇到類似的問題,這是因為您另一個組件中定義MyChildCmp 當你這樣做時,在父組件的每次渲染中,函數MyChildCmp都會重新創建,並且 react 的協調算法認為你在下一次渲染時渲染了不同的組件類型,因此它會破壞組件實例。 將該組件的定義移到父組件之外。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM