score:1

here's an example how you could do it.

as you can see child became presentational component and only shows data.

rest of logic went to the parent component.

const { usestate, useeffect, fragment } = react;

const child = ({nr, user, onaddfield, onchange}) => {

  return <div>
    <div>{nr}</div>
    {user.map(({firstname, lastname}, index) => <div key={index}>
    <input onchange={({target: {name, value}}) => onchange(nr, index, name, value)} value={firstname} name="firstname" type="text"/>
    <input onchange={({target: {name, value}}) => onchange(nr, index, name, value)} value={lastname} name="lastname" type="text"/>
    </div>)}
    <button onclick={() => onaddfield(nr)}>add field</button>
  </div>
}

const app = () => {
  const [items, setitems] = usestate([
  {
    nr: 1,
    user: []
  },
  {
    nr: 2,
    user: [
      {firstname: 'test1', lastname: 'test1'},
      {firstname: 'test2', lastname: 'test2'}
    ]
  }
  ]);  

  const oncountchange = ({target: {value}}) => {
    
    setitems(items => {
      const computedlist = array(number(value)).fill(0).map((pr, index) => ({
        nr: index + 1,
        user: []
      }))
      
      const merged = computedlist.reduce((acc, value) => {
        const item = items.find(pr => pr.nr === value.nr) || value;
        
        acc = [...acc, item];
        
        return acc;
      }, [])
      
      return merged;
    })
    
  }

  const onchildchange = (nr, index, name, value) => {
    setitems(items => {
      const newitems = [...items];
      const item = newitems.find(pr => pr.nr === nr);
      const field = item.user.find((pr, ind) => index === ind)
      field[name] = value;
      
      return newitems;
    });
  }
  
  const onaddfield = (nr) => {
    setitems(items => {

      const newitems = [...items];
      const item = newitems.find(pr => pr.nr === nr);
      item.user = [...item.user, {
        firstname: '',
        lastname: ''
      }];

      return newitems;
    })
  }

  const onclick = () => {
    console.log({data: items});
  }

  return <div>
    {items.map((pr, index) => <child {...pr} onaddfield={onaddfield} onchange={onchildchange} key={index} />)}
    <input onchange={oncountchange} value={items.length} type="number"/>
    <button onclick={onclick}>submit</button>
  </div>
}

reactdom.render(
    <app />,
    document.getelementbyid('root')
  );
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>


Related Query

More Query from same tag