React-如何与Parent共享子组件状态



背景

所以我有一个简单的例子,一个Form组件(Parent)和多个Input组件(Children)。每个单独的Input组件都将有一个useState钩子来初始化和管理其值的状态。

问题

与大多数表单一样,我希望将所有数据提交到后端进行处理。然而,问题是我无法从每个子输入组件中检索值的状态。

// app.jsx
import Form from "./Form";
export default function App() {
return <Form />;
}
// Form.jsx
import React from "react";
import Input from "./Input";
const handleSubmit = (e) => {
e.preventDefault();
console.log("Wait, how do I retreive values from Children Inputs?");
};
const Form = () => {
console.log("Form render");
return (
<form onSubmit={handleSubmit}>
Sample Form
<Input initial="username" name="user" />
<Input initial="email" name="email" />
<button type="submit">Submit</button>
</form>
);
};
export default Form;

// Input.jsx
import React from "react";
import useInputValue from "./useInputValue";
const Input = ({ name, initial }) => {
const inputState = useInputValue(initial);
console.log(`${name}'s value: ${inputState.value}`);
return <input {...inputState} />;
};
export default Input;

合理的解决方案

当然,我可以将Input状态提升到Form组件,也许是在obj名称值中。但是,如果我这样做,每次更改输入时,Form都会重新渲染,同时所有的输入。

对我来说,这是不可取的副作用。随着我的Form组件越来越大,每当一个输入发生变化时,重新呈现所有输入(表单内)的成本就会更高。

正因为如此,我想坚持我的决定,让每个单独的输入管理自己的状态,这样,如果一个输入发生变化,并不是所有其他输入都会与父组件一起重新渲染。

问题

如果每个子组件都管理自己的状态,那么父组件是否可以访问该状态的值并执行操作(如表单提交)?

更新

许多回答和评论都提到,这是过早的优化,是所有已知邪恶的根源;我同意,但为了澄清,我用一个简单的例子来问这个问题,因为我想为我目前更复杂的项目找到一个可行的解决方案。我的网络应用程序有一个巨大的表单(所有状态都提升到表单级别),每次输入更改时都会重新呈现。这似乎没有必要,因为一次只更改一个输入。

更新#2以下是我遇到的问题的代码沙盒示例。有两种表单,一种是所有状态由单独的Child输入组件管理,另一种是在表单级别提升所有状态。请尝试输入一些值并检查控制台中的日志消息。可以看到,随着所有状态提升到表单级别,每一次更改都会导致两个输入都被重新呈现。

我认为是的,您可以共享状态。还有3个选项:

  1. 我建议您使用Formik这样的库。这对你的情况会有所帮助
  2. 您可以使用useState()钩子作为道具来共享状态
  3. 使用诸如Redux Toolkit(如果我们谈论的是记忆)、useContext()等工具

如果您想要从输入中获得最终值,请为每个输入分配ref,并使用submit函数中的emailRef.current.value进行访问。

import { useState, useRef, forwardRef } from 'React';

const Input = forwardRef((props, ref) => {
const [value, setValue] = useState('');
return <input ref={ref} value={value} onChange={(e) => {setValue(e.target.value)}} {...props} />;
});

const App = () => {
const emailRef = useRef(null);

const submit = () => {
const emailString = emailRef.current.value
};

return (
<>
<Input ref={emailRef} />
<button onClick={submit}>Submit</button>
</>
);
};

如果家长需要了解孩子的状态,您可以

  1. 向上移动状态。这是通过传递子级调用的setState函数来解决的(状态数据在父级中可用)
  2. 使用上下文https://reactjs.org/docs/context.html
  3. 使用状态管理库,例如redux

在你的简单情况下,我会选择1)

最新更新