我有一个父组件,它在一个对象数组中保存其所有子组件的信息值。我正在尝试产生一个新的孩子,并以对象数组的形式跟踪那些处于我父母状态的孩子的信息。这是我不知道如何在两个方面进行处理的地方。跟踪状态内的对象并从孩子那里获取内容。
我有一个父级组件:
const Parent: React.FC = () => {
const [children, setChildren] = React.useState(
[
{
id:1,
name:'',
age:0,
}
]
);
const getChildName = () => {
// not sure how to target the new child
}
// Create a new child
const AddChild = () => {
let tmpid = children[children.length].id + 1; // not sure if this would work
setChildren(
[
...children,
{
id:tmpid,
name:' ',
age:0,
}
]
)
}
return (
<button onClick={this.addChild}>Add component</button>
{
children.map((child) => (
<NewChild key={child.id} getChildName={getChildName} getChildAge={getChildAge}/>
))
}
)
}
然后是一个简单的子组件:
interface IChild {
name?: string;
age?: number;
}
type Props = {
getChildName : void,
getChildAge : void,
}
const NewChild: React.FC<Props> = (Props) => {
const [child, setChild] = React.useState<Partial<IChild>>({});
return (
<input value={child?.name??''} onChange={e => setChild({...child , child: e.target.value})}/>
<input value={child?.age??''} onChange={e => setChild({...child , child: parseFloat(e.target.value)})}/>
)
}
答案 0 :(得分:1)
看看我如何实现下面的getChildName。它未经测试,但我认为它应该可以工作。还要看一下代码中的注释。如果需要实现getChildAge,则可以执行与getChildName相同的操作,但是返回newChild.age
。
const Parent: React.FC = () => {
const [children, setChildren] = React.useState(
[
{
id:1,
name:'',
age:0,
}
]
);
const getChildName = (id: number) => {
let newChild = null;
children.forEach((child) => {
if (child.id == id) {
newChild = child;
}
}
return !!newChild ? newChild.name : `No child was found with id ${id}`
}
// Create a new child
const AddChild = () => {
/* let tmpid = children[children.length].id + 1; -- this will work. */
let tmpid = children.length + 1 // This is cleaner, and as long as your id starts on 1,
// this will be the exact same result.
setChildren(
[
...children,
{
id:tmpid,
name:' ',
age:0,
}
]
)
}
return (
<button onClick={this.addChild}>Add component</button>
{
children.map((child) => (
// You need to add return here.
return <NewChild key={child.id} getChildName={(child.id) => getChildName(child.id)} getChildAge={getChildAge}/>
))
}
)
}
就像johnrsharpe所说的那样,不要在两个地方管理相同的状态。您需要给NewChild这样的回调:
<NewChild // Inside Render() method of <Parent />
key={child.id}
getChildName={(child.id) => getChildName(child.id)}
getChildAge={getChildAge}
callback={updateChildren}
/>
const updateChildren = (inputChild: IChild) => { // Method of <Parent />
const newChildren = children.map((child) => {
if (child.id = inputChild.id) {
child.name = inputChild.name;
child.age = inputChild.age;
}
return child;
}
setChildren([ ...newChildren ]);
}
在NewChild组件中,而不是使用setChild状态,您可以将对象传递给
之类的函数。const changeChildProperty = (value: any) => {
// update property of child
// Pass in the entire child object, and it will be update in parent state through the callback
props.callback(child);
}