[英]How to update a parent's component state from a child component in Reactjs
[英]Reactjs: How to access state of child component.from a method in parent component that depends on state of child component
我需要訪問父組件中定義的方法handleCancelEdit()
。 但是,這里的問題是每個子組件都有自己的cancelEdit
state。 現在,正在發生的事情是,如果我從一個子組件調用handleCancelEdit()
,則每個其他相同的子組件都在使用 state 並更新自己(該方法尚未完全定義)。 這就是為什么,我在子組件中定義了cancelEdit
state,認為它只屬於這個子組件。
現在,如何使handleCancelEdit()
方法更改調用它的唯一子組件?
家長:
function Parent() {
const handleCancelEdit = () => {
setCancelEdit(!cancelEdit); // defined in child component
setEdit(!edit); // defined in child component
...
};
return (
<div>
<ChildComponent
fieldName={"Email"}
value={email}
inputType={"text"}
placeHolder={"Enter email"}
name={"email"}
on_change={(e)=>setEmail(e.target.value)}
on_click={handleUserEmail}
/>
<ChildComponent
fieldName={"About"}
value={about}
inputType={"text"}
placeHolder={"Enter some details about yourself"}
name={"about"}
on_change={(e)=>setAbout(e.target.value)}
on_click={handleUserAbout}
/>
</div>
);
}
子組件:
function ChildComponent({fieldName, value, inputType, placeHolder, name, on_change, on_click}) {
const [ edit, setEdit ] = useState(false);
const [ cancelEdit, setCancelEdit ] = useState(false)
const isEdit = edit;
return (
<p>{fieldName}: {value === ''? (
<span>
<input type={inputType} placeholder={placeHolder}
name={name} onChange={on_change}
/>
<button type="submit" onClick={on_click}>Add</button>
</span>
) : ( !isEdit ? (<span> {value} <button onClick={e=>setEdit(!edit)}>Edit</button></span>) :
(<span>
<input type={inputType} value={value}
name={name} onChange={on_change}
/>
<button type="submit" onClick={on_click}>Save</button>
<button type="submit" onClick={handleCancelEdit}>Cancel</button>
</span>)
)}
</p>
);
};
我希望它可以理解一個子組件不應該讓其他組件更新。 現在,在這種情況下我該怎么做?
編輯
即使父子組件中的onChange
正確,子組件中的輸入字段也不起作用!
將 state 和數據向下傳遞而不是向上傳遞總是更合乎邏輯。 如果Parent
級需要與edit
state 交互,那么 state 應該存在於父級中。 當然,我們希望每個孩子都有獨立的edit
狀態,所以父母不能只有一個boolean
。 每個孩子都需要一個boolean
。 我推薦一個object
由字段的name
屬性鍵入。
在ChildComponent
中,我們將isEdit
和setEdit
移動到 props。 handleCancelEdit
只是() => setEdit(false)
(是否還需要清除onChange
設置的 state ?)。
function ChildComponent({fieldName, value, inputType, placeHolder, name, onChange, onSubmit, isEdit, setEdit}) {
return (
<p>{fieldName}: {value === ''? (
<span>
<input type={inputType} placeholder={placeHolder}
name={name} onChange={onChange}
/>
<button type="submit" onClick={onSubmit}>Add</button>
</span>
) : ( !isEdit ? (<span> {value} <button onClick={() =>setEdit(true)}>Edit</button></span>) :
(<span>
<input type={inputType} value={value}
name={name} onChange={onChange}
/>
<button type="submit" onClick={onSubmit}>Save</button>
<button type="submit" onClick={() => setEdit(false)}>Cancel</button>
</span>)
)}
</p>
);
};
在Parent
中,我們需要存儲這些isEdit
狀態,並為每個字段創建一個setEdit
function。
function Parent() {
const [isEditFields, setIsEditFields] = useState({});
const handleSetEdit = (name, isEdit) => {
setIsEditFields((prev) => ({
...prev,
[name]: isEdit
}));
};
/* ... */
return (
<div>
<ChildComponent
fieldName={"Email"}
value={email}
inputType={"text"}
placeHolder={"Enter email"}
name={"email"}
onChange={(e) => setEmail(e.target.value)}
onSubmit={handleUserEmail}
isEdit={isEditFields.email}
setEdit={(isEdit) => handleSetEdit("email", isEdit)}
/>
<ChildComponent
fieldName={"About"}
value={about}
inputType={"text"}
placeHolder={"Enter some details about yourself"}
name={"about"}
onChange={(e) => setAbout(e.target.value)}
onSubmit={handleUserAbout}
isEdit={isEditFields.about}
setEdit={(isEdit) => handleSetEdit("about", isEdit)}
/>
</div>
);
}
您可以通過將values
存儲為單個 state 而不是單個useState
掛鈎來清理大量重復的代碼。 現在 5 個 props 可以僅從name
自動生成。
function Parent() {
const [isEditFields, setIsEditFields] = useState({});
const [values, setValues] = useState({
about: '',
email: ''
});
const getProps = (name) => ({
name,
value: values[name],
onChange: (e) => setValues(prev => ({
...prev,
[name]: e.target.value
})),
isEdit: isEditFields[name],
setEdit: (isEdit) => setIsEditFields(prev => ({
...prev,
[name]: isEdit
}))
});
const handleUserEmail = console.log // placeholder
const handleUserAbout = console.log // placeholder
return (
<div>
<ChildComponent
fieldName={"Email"}
inputType={"text"}
placeHolder={"Enter email"}
onSubmit={handleUserEmail}
{...getProps("email")}
/>
<ChildComponent
fieldName={"About"}
inputType={"text"}
placeHolder={"Enter some details about yourself"}
onSubmit={handleUserAbout}
{...getProps("about")}
/>
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.