问题描述
我想使用按钮将输入与位于同一组件的内容分开,因此我将它们放在另一个组件上,但是问题在于访问父组件中的那些状态,以便我可以捕获它们并在提交中使用这些值,那么我该如何解决呢?
export default function Parent() {
const handleSubmit = () => {
console.log(name,email); // I wanna access those child states here
}
return (
<div>
<Form />
<button onClick={handleSubmit}>Submit</button>
</div>
);
};
export default function Child() {
const [name,setName] = useState('')
const [email,setEmail] = useState('')
return (
<form>
<input placeholder="name" value={name} onChange={e => setName(e.target.value)} />
<input placeholder="email" value={email} onChange={e => setEmail(e.target.value)} />
</form>
);
};
解决方法
您可以lift the state up,使其在父级上存在并传递给子级,以便双方都可以查看和使用它:
function Parent() {
const [name,setName] = React.useState('')
const [email,setEmail] = React.useState('')
const handleSubmit = () => {
console.log(name,email); // I wanna access those child states here
}
return (
<div>
<Child {...{ name,setName,email,setEmail }} />
<button onClick={handleSubmit}>Submit</button>
</div>
);
};
function Child({ name,setEmail }) {
return (
<form>
<input placeholder="name" value={name} onChange={e => setName(e.target.value)} />
<input placeholder="email" value={email} onChange={e => setEmail(e.target.value)} />
</form>
);
};
ReactDOM.render(<Parent />,document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class="react"></div>
,
更好地在父组件而不是子组件中创建和处理钩子。
export default function Parent() {
const [name,setName] = useState('')
const [email,setEmail] = useState('')
const handleSubmit = () => {
console.log(name,email); // I wanna access those child states here
}
return (
<div>
<Child name={name} email={email}
setName={setName}
setEmail={setEmail}
/>
<button onClick={handleSubmit}>Submit</button>
</div>
);
};
function Child(props) {
const {name,setEmail } = props;
return (
<form>
<input placeholder="name" value={name} onChange={e => setName(e.target.value)} />
<input placeholder="email" value={email} onChange={e => setEmail(e.target.value)} />
</form>
);
};
,
您可以将状态保留在父组件中,并将state和setState作为道具传递给子组件,子组件的职责是显示其作为输入和调用处理程序所获得的内容(即setState由父组件传递给道具)是否有变化元素
,父母将无法直接访问Child内部的状态。
一种解决方案是根据某些性能的建议提高状态。
另一种解决方案是在子对象内部使用“提交”按钮,并传递回调以访问“提交”上的输入值,以避免传递太多不同的道具。
export default function Parent() {
const handleSubmit = (name,email) => {
// do whatever you want with name and email here
console.log(name,email);
}
return (
<div>
<Form onSubmit={handleSubmit} />
</div>
);
};
export default function Child({onSubmit}) {
const [name,setEmail] = useState('')
return (
<form>
<input placeholder="name" value={name} onChange={e => setName(e.target.value)} />
<input placeholder="email" value={email} onChange={e => setEmail(e.target.value)} />
<button onClick={()=>onSubmit(name,email)}>submit</button>
</form>
);
};```
,
使用道具将父函数传递给子函数。提交子表单后,它将调用父表单。另外,您也可以按照其他答案的建议解除状态,这是个好主意。
请注意,子组件不会处理表单提交,如果用户在其中一个文本框中按下Enter键,则会触发重新加载。
这样的事情(不是提升状态,但是您也可以这样做):
export default function Parent() {
const handleSubmit = (name,email) => {
console.log(name,email); // I wanna access those child states here
}
return (
<div>
<Form onSubmit={handleSubmit} />
</div>
);
};
export default function Child({onSubmit}) {
const [name,setEmail] = useState('')
return (
<form onSubmit={e => { e.preventDefault(); onSubmit(name,email); }}>
<input placeholder="name" value={name} onChange={e => setName(e.target.value)} />
<input placeholder="email" value={email} onChange={e => setEmail(e.target.value)} />
<button>Submit</button>
</form>
);
};