使用 React Hooks 将输入传递到 Child 组件更新输入值
Updating Input Value with Input Passed Into Child Component with React Hooks
我有一个加载组件,它创建一个骨架,直到内容通过 @trainline/react-skeletor
呈现。在这种情况下,我正在为表单创建骨架。
首先,我有一个 CodeSandbox 给那些想看看发生了什么的人,所有的组件都用于更好地了解解决方案。
我也在使用基于函数的组件,并希望保持这种状态,除非通过基于函数的组件无法做到这一点我不想使用基于 Class 的组件来解决这个问题问题。
我有一个组件 ProfileForm
,目前包含一个 h3
和一个 form
表格如下
const form = (
<>
<FormControl key={"profileForm"} submit={profileFormSubmit} form={profileFormData} validation={profileFormValidation}>
<InputControl autoComplete="off" type="text" name="emailAddress" placeholder="Email address" label="Email Address">
<ErrorMsg map="required" msg="Email is required"></ErrorMsg>
</InputControl>
</FormControl>
</>
)
FormControl
组件 return 是一个 <form>
元素
InputControl
组件 return 是一个 <label>
和 <input>
元素
ErrorMsg
组件 return 一个 <div>
将呈现如下。
<form class="Form " novalidate="">
<div class="InputControl">
<div>
<label for="emailAddress">Email Address</label>
<input type="text" placeholder="Email address" name="emailAddress" id="emailAddress" autocomplete="off" value=""></div>
<div class="InputControl--Errors">
</div>
</div>
</form>
我创建了一个虚拟 http 请求,我在其中更新状态 object,其中包含标题和上述表格。
const [content, setContent] = useState();
const ttl = 500;
/*simulate http request*/
useEffect(() => {
const timeout = setTimeout(() => {
setContent({ title: "My Personal Details", form });
}, ttl);
return () => {
clearTimeout(timeout);
};
}, []);
在我的 return 中,我将 content
状态 object 作为道具传递(注释掉的代码有效,但不会创建我的中所需的骨架加载元素项目
return (
<div className="ProfileForm">
<h2 style={{ color: "red" }}>Not working: Passing Form Down to Child</h2>
<ProfileFormContainer content={content} />
{/* <h2 style={{ color: 'green' }}>Working: Render Directly in return</h2>
{form}*/}
</div>
);
ProfileFormContainer
创建骨架元素,然后将道具向下传递到另一个组件,并在下面的代码片段中得到 returned。
const Wrapper = createSkeletonElement('div', 'Loader Loader--InlineBlock ProfileForm--loading');
const H3 = createSkeletonElement('h3', 'Loader Loader--InlineBlock');
const DIV = createSkeletonElement('div', 'Loader Loader--Block ');
const ProfileFormLoader = (props) => {
return (
<Wrapper className="ProfileForm">
<H3 className="ProfileForm-title">{ props.title }</H3>
<DIV>
{props.form}
</DIV>
</Wrapper>
);
}
export default ProfileFormLoader;
这按预期呈现,但是,当我尝试输入输入时,它不会更新输入的值。我的问题是,当输入作为道具传递给 child 组件时,如何更新输入的值?
如有任何帮助,我们将不胜感激
事情是这样的:
您基本上只显示 useState
中的 content
您模拟您的 httpRequest,它将 content
更新为空表单
然后你再也不会更新 content
,它仍然是第一次渲染时的空表格。
当您将 form
保留在 content
之外时它会起作用,因为 form
在每次渲染时都会使用实际的 profileFormData
.
进行评估
我建议不要使用状态来存储您的案例中的节点(可能还有大多数其他案例)。您的 http 请求的 return 应该填充您的模板可以从中读取的数据存储,但考虑到您的表单也需要从其他来源读取的事实,例如当前输入状态,保持 form
在渲染中,它将在每次渲染时更新。
我有一个加载组件,它创建一个骨架,直到内容通过 @trainline/react-skeletor
呈现。在这种情况下,我正在为表单创建骨架。
首先,我有一个 CodeSandbox 给那些想看看发生了什么的人,所有的组件都用于更好地了解解决方案。
我也在使用基于函数的组件,并希望保持这种状态,除非通过基于函数的组件无法做到这一点我不想使用基于 Class 的组件来解决这个问题问题。
我有一个组件 ProfileForm
,目前包含一个 h3
和一个 form
表格如下
const form = (
<>
<FormControl key={"profileForm"} submit={profileFormSubmit} form={profileFormData} validation={profileFormValidation}>
<InputControl autoComplete="off" type="text" name="emailAddress" placeholder="Email address" label="Email Address">
<ErrorMsg map="required" msg="Email is required"></ErrorMsg>
</InputControl>
</FormControl>
</>
)
FormControl
组件 return 是一个 <form>
元素
InputControl
组件 return 是一个 <label>
和 <input>
元素
ErrorMsg
组件 return 一个 <div>
将呈现如下。
<form class="Form " novalidate="">
<div class="InputControl">
<div>
<label for="emailAddress">Email Address</label>
<input type="text" placeholder="Email address" name="emailAddress" id="emailAddress" autocomplete="off" value=""></div>
<div class="InputControl--Errors">
</div>
</div>
</form>
我创建了一个虚拟 http 请求,我在其中更新状态 object,其中包含标题和上述表格。
const [content, setContent] = useState();
const ttl = 500;
/*simulate http request*/
useEffect(() => {
const timeout = setTimeout(() => {
setContent({ title: "My Personal Details", form });
}, ttl);
return () => {
clearTimeout(timeout);
};
}, []);
在我的 return 中,我将 content
状态 object 作为道具传递(注释掉的代码有效,但不会创建我的中所需的骨架加载元素项目
return (
<div className="ProfileForm">
<h2 style={{ color: "red" }}>Not working: Passing Form Down to Child</h2>
<ProfileFormContainer content={content} />
{/* <h2 style={{ color: 'green' }}>Working: Render Directly in return</h2>
{form}*/}
</div>
);
ProfileFormContainer
创建骨架元素,然后将道具向下传递到另一个组件,并在下面的代码片段中得到 returned。
const Wrapper = createSkeletonElement('div', 'Loader Loader--InlineBlock ProfileForm--loading');
const H3 = createSkeletonElement('h3', 'Loader Loader--InlineBlock');
const DIV = createSkeletonElement('div', 'Loader Loader--Block ');
const ProfileFormLoader = (props) => {
return (
<Wrapper className="ProfileForm">
<H3 className="ProfileForm-title">{ props.title }</H3>
<DIV>
{props.form}
</DIV>
</Wrapper>
);
}
export default ProfileFormLoader;
这按预期呈现,但是,当我尝试输入输入时,它不会更新输入的值。我的问题是,当输入作为道具传递给 child 组件时,如何更新输入的值?
如有任何帮助,我们将不胜感激
事情是这样的:
您基本上只显示 useState
content
您模拟您的 httpRequest,它将 content
更新为空表单
然后你再也不会更新 content
,它仍然是第一次渲染时的空表格。
当您将 form
保留在 content
之外时它会起作用,因为 form
在每次渲染时都会使用实际的 profileFormData
.
我建议不要使用状态来存储您的案例中的节点(可能还有大多数其他案例)。您的 http 请求的 return 应该填充您的模板可以从中读取的数据存储,但考虑到您的表单也需要从其他来源读取的事实,例如当前输入状态,保持 form
在渲染中,它将在每次渲染时更新。