如何在父组件中将不同子组件的数据保存到单个数组

问题描述 投票:0回答:2

这里我有三个组件。每当我单击任何子组件(

First
Second
)中的按钮时,父(
Test
)组件应该显示输入到子组件中的文本。问题是每当我单击其他子组件的按钮时,都会使用来自该特定组件的数据创建一个新数组。 这是代码:

测试组件:

function Test() {
    const [ChildData , setChildData] = useState('');
    
    console.log(ChildData)

  return (
    <div>
        <h1>Test</h1>
        <div>
            {ChildData? <div>{ChildData.map((data)=>{return <div>{data}</div> })}</div>:null }
        </div>
        <First passChildData={setChildData}/>
        <Second passChildData={setChildData}/>       
    </div>
  )
}

第一部分:

function First(props) {

  const [Data, setData] = useState('');
  const [Items, setItems] = useState('')

  const handlechange = (e)=>{
    setData(e.target.value)
  }
  const handleClick = ()=>{
    if(Data != ''){
      setItems((prevData)=>{
        const newData = [...prevData,Data];
        props.passChildData(newData)
        return newData
      })
      setData('')
    }else{
      console.log("enter something")
    }
  }

  return (
    <div>
        <h1>First</h1>
        <input type="text" onChange={handlechange} value={Data}/>
        <button onClick={handleClick}>Add</button>
        {Data}
        <div>{Items? <div>{Items.map((item)=>{return <div>{item}</div> })}</div>:null }</div>
    </div>
  )
}

第二部分:

function Second(props) {
  
  const [Data, setData] = useState('');
  const [Items, setItems] = useState('')

  const handlechange = (e)=>{
    setData(e.target.value)
  }
  const handleClick = ()=>{
    if(Data != ''){
      setItems((prevData)=>{
        const newData = [...prevData,Data];
        props.passChildData(newData)
        return newData
      })
      setData('')
    }else{
      console.log("enter something")
    }
  }

  return (
    <div>
        <h1>Second</h1>
        <input type="text" onChange={handlechange} value={Data}/>
        <button onClick={handleClick}>Add</button>
        {Data}
        <div>{Items? <div>{Items.map((item)=>{return <div>{item}</div> })}</div>:null }</div>
    </div>
  )
}

我期待的是:

  • 当我在
    First
    组件中输入“What”时;
  • 然后“是”进入
    Second
    组件;
  • 然后“你的”进入
    First
    组件
  • 然后“名字?”在
    Second
    组件

我想要“你叫什么名字?” (不管它是在不同的 div 还是在行中;我希望每个项目都按照输入的顺序显示)显示在父 (

Test
) 组件中。

javascript reactjs react-hooks react-props
2个回答
1
投票

首先,我不会有两个组件 -

First
Second
- 除了它们的标题外几乎相同;我会有一个带有
heading
作为道具的组件。

其次,我会使用带有

<form>
处理程序的
onSubmit
而不是带有
<button>
处理程序的
onClick
因为这将允许用户添加项目,例如,在输入时按 [Enter]领域有重点。

第三,我会使用

useEffect
钩子来监听
First
组件对
Items
数组的变化,然后在有变化时调用
passChildData
prop 函数。请注意,引用数组的变量应使用空数组进行初始化,例如:
const [Items, setItems] = useState([])
.

最终代码如下:

function Test() {
  const [ChildData, setChildData] = useState([]);

  const setItem = (newItem) => {
    setChildData([...ChildData, newItem]);
  }

  return (
    <div>
        <h1>Test</h1>
        <div>
          {ChildData.map((data, index) => <div key={index}>{data}</div>)}
        </div>
        <First heading="First" passChildData={setItem}/>
        <First heading="Second" passChildData={setItem}/>
    </div>
  )
}

function First(props) {
  const [Data, setData] = useState('');
  const [Items, setItems] = useState([])
  
  useEffect(() => {
    props.passChildData(Data);
  }, [Items])

  const handlechange = (e)=>{
    setData(e.target.value)
  }
  
  const handleSubmit = (e) => {
    e.preventDefault();

    if (Data === '') {
        console.log('enter something');
    } else {
        setItems([...Items, Data]);
    }
  }

  return (
    <div>
        <h1>{props.heading}</h1>
        <form onSubmit={handleSubmit}>
          <input type="text" onChange={handlechange} value={Data}/>
          <button type="submit">Add</button>
          {Data}
        </form>
        <div>
          {Items.map((item, index) => <div key={index}>{item}</div>)}
        </div>
    </div>
  )
}

我创建了一个fiddle供参考。


0
投票

问题是您正在改变每个组件中的整个状态。换句话说,你不使用

prevData
。 我会改变 First 和 Second 组件的
onClick
方法的状态,像这样:

setItems((prevData)=>{
        const newData = [***...prevData***, ...Items,Data];
        props.passChildData(newData)
        return newData
      })
© www.soinside.com 2019 - 2024. All rights reserved.