将 parent 状态替换为 child 状态。 parent 中的按钮
Replace parent state with state of child. Button in parent
编辑: 请参阅 O.o 的评论以了解答案的解释以及您使用 类 时的变体。
我遇到了一些问题,但找不到解决方案。
我的网络应用程序中有 4 个组件:
Parent
child_1
child_2
child_3
我在 Parent 上有一个按钮,在 children 上有不同的表单(带有输入、复选框和单选按钮)。
每个 child 都有自己的按钮,可以执行多个功能、一些计算并更新相应的状态。 (没有状态通过 parent 和 child)。
我需要把children的三个按钮换成parent按钮。
有没有办法可以通过 parent 按钮执行三个 children 的功能并检索结果? (结果是 state:value
每 child。)
function Child1(props) {
const [value, setValue] = useState("");
useEffect(() => {
calculate();
}, [props.flag]);
calculate() {
//blah blah
}
onChange(e) {
setValue(e.target.value);
props.onChange(e.target.value); // update the state in the parent component
}
return (
<input value={value} onChange={(e) => onChange(e)} />
);
}
function Parent(props) {
const [flag, setFlag] = useState(false);
const [child1Value, setChild1Value] = useState("");
return (
<div>
<Child1 flag={flag} onChange={(value) => setChild1Value(value)}/>
<button onClick={() => setFlag(!flag)} />
</div>
);
}
我没有对此进行测试,但希望对您有所帮助。让我知道是否有问题。
尝试以下操作:
- 使用
useRef
为 child 表单组件创建引用。
- 对于功能组件,为了让parent访问child的方法,你需要使用
forwardRef
- 使用 ref,在单击 parent 提交按钮时调用 child 组件函数(使用
ref.current.methodName
)
查看示例代码。我在本地测试过,没问题。
Parent
import React, { Fragment, useState, useRef } from "react";
import ChildForm1 from "./ChildForm1";
const Parent = props => {
const [form1Data, setFormData] = useState({});//use your own data structure..
const child1Ref = useRef();
// const child2Ref = useRef(); // for 2nd Child Form...
const submitHandler = e => {
e.preventDefault();
// execute childForm1's function
child1Ref.current.someCalculations();
// execute childForm2's function
// finally do whatever you want with formData
console.log("form submitted");
};
const notifyCalcResult = (calcResult) => {
// update state based on calcResult
console.log('calcResult', calcResult);
};
const handleChildFormChange = data => {
setFormData(prev => ({ ...prev, ...data }));
};
return (
<Fragment>
<h1 className="large text-primary">Parent Child demo</h1>
<div>
<ChildForm1
notifyCalcResult={notifyCalcResult}
ref={child1Ref}
handleChange={handleChildFormChange} />
{/*{do the same for ChildForm2 and so on...}*/}
<button onClick={submitHandler}>Final Submit</button>
</div>
</Fragment>
);
};
export default Parent;
ChildFormComponent
import React, { useState, useEffect, forwardRef, useImperativeHandle } from "react";
const ChildForm1 = ({ handleChange, notifyCalcResult }, ref) => {
const [name, setName] = useState("");
const [calcResult, setCalcResult] = useState([]);
const someCalculations = () => {
let result = ["lot_of_data"];
// major calculations goes here..
// result = doMajorCalc();
setCalcResult(result);
};
useImperativeHandle(ref, () => ({ someCalculations }));
useEffect(() => {
// notifiy parent
notifyCalcResult(calcResult);
}, [calcResult]);
return (
<form className="form">
<div className="form-group">
<input
value={name}// //TODO: handle this...
onChange={() => handleChange(name)}//TODO: notify the value back to parent
type="text"
placeholder="Enter Name"
/>
</div>
</form>
);
};
export default forwardRef(ChildForm1);
同样作为最佳实践,考虑尽可能维护 parent 组件中的状态和功能,并将所需的 values/methods 作为 props 传递给 child。
编辑: 请参阅 O.o 的评论以了解答案的解释以及您使用 类 时的变体。
我遇到了一些问题,但找不到解决方案。
我的网络应用程序中有 4 个组件:
Parent
child_1
child_2
child_3
我在 Parent 上有一个按钮,在 children 上有不同的表单(带有输入、复选框和单选按钮)。
每个 child 都有自己的按钮,可以执行多个功能、一些计算并更新相应的状态。 (没有状态通过 parent 和 child)。
我需要把children的三个按钮换成parent按钮。
有没有办法可以通过 parent 按钮执行三个 children 的功能并检索结果? (结果是 state:value
每 child。)
function Child1(props) {
const [value, setValue] = useState("");
useEffect(() => {
calculate();
}, [props.flag]);
calculate() {
//blah blah
}
onChange(e) {
setValue(e.target.value);
props.onChange(e.target.value); // update the state in the parent component
}
return (
<input value={value} onChange={(e) => onChange(e)} />
);
}
function Parent(props) {
const [flag, setFlag] = useState(false);
const [child1Value, setChild1Value] = useState("");
return (
<div>
<Child1 flag={flag} onChange={(value) => setChild1Value(value)}/>
<button onClick={() => setFlag(!flag)} />
</div>
);
}
我没有对此进行测试,但希望对您有所帮助。让我知道是否有问题。
尝试以下操作:
- 使用
useRef
为 child 表单组件创建引用。 - 对于功能组件,为了让parent访问child的方法,你需要使用
forwardRef
- 使用 ref,在单击 parent 提交按钮时调用 child 组件函数(使用
ref.current.methodName
)
查看示例代码。我在本地测试过,没问题。
Parent
import React, { Fragment, useState, useRef } from "react";
import ChildForm1 from "./ChildForm1";
const Parent = props => {
const [form1Data, setFormData] = useState({});//use your own data structure..
const child1Ref = useRef();
// const child2Ref = useRef(); // for 2nd Child Form...
const submitHandler = e => {
e.preventDefault();
// execute childForm1's function
child1Ref.current.someCalculations();
// execute childForm2's function
// finally do whatever you want with formData
console.log("form submitted");
};
const notifyCalcResult = (calcResult) => {
// update state based on calcResult
console.log('calcResult', calcResult);
};
const handleChildFormChange = data => {
setFormData(prev => ({ ...prev, ...data }));
};
return (
<Fragment>
<h1 className="large text-primary">Parent Child demo</h1>
<div>
<ChildForm1
notifyCalcResult={notifyCalcResult}
ref={child1Ref}
handleChange={handleChildFormChange} />
{/*{do the same for ChildForm2 and so on...}*/}
<button onClick={submitHandler}>Final Submit</button>
</div>
</Fragment>
);
};
export default Parent;
ChildFormComponent
import React, { useState, useEffect, forwardRef, useImperativeHandle } from "react";
const ChildForm1 = ({ handleChange, notifyCalcResult }, ref) => {
const [name, setName] = useState("");
const [calcResult, setCalcResult] = useState([]);
const someCalculations = () => {
let result = ["lot_of_data"];
// major calculations goes here..
// result = doMajorCalc();
setCalcResult(result);
};
useImperativeHandle(ref, () => ({ someCalculations }));
useEffect(() => {
// notifiy parent
notifyCalcResult(calcResult);
}, [calcResult]);
return (
<form className="form">
<div className="form-group">
<input
value={name}// //TODO: handle this...
onChange={() => handleChange(name)}//TODO: notify the value back to parent
type="text"
placeholder="Enter Name"
/>
</div>
</form>
);
};
export default forwardRef(ChildForm1);
同样作为最佳实践,考虑尽可能维护 parent 组件中的状态和功能,并将所需的 values/methods 作为 props 传递给 child。