У меня есть два текстовых поля, я хочу обновить свое состояние с помощью функции setState ниже. но если я console.log (state.users), он продолжает создавать массивы. Мне просто нужен один массив и обновленный объект внутри.

const [state, setState] = useState({
    pm: ""
    users: [],
  });

Это моя функция смены ручки.

const handleChange = (e) => {
  
    setState(prev=>{
     return {...prev.state, users:[...prev.users, {[e.targe.name]:e.target.value}] }
    })
    
  };
              <TextField    
                id="user1"
                label="user1"
                name="user1"
                onChange={handleChange}
              
              >{console.log(state)}
             </TextField>
              
              <TextField
              
                id="user2"
                label="user2"
                name="user2"
                onChange={handleChange}
               
                required
              ></TextField>
//expected console.log(state)
{users: Array(1)}
//inside of array I expects
{user1: value,
 user2: value,
}

//but currently it gives me this, it keep generates multiple arrays everytime I //change something..
{users: Array(1)}
{users: Array(2)}
{users: Array(3)}
{users: Array(4)}
0
H K 25 Июл 2020 в 00:49

1 ответ

Лучший ответ

Это потому, что вы добавляете свой prev.state с помощью ...prev.state, поэтому он будет продолжать просто добавлять поверх того, что уже есть.

==== ОБНОВЛЕНИЕ 1 ====

См. Код ниже, нажав R фрагмент кода un .

const { useState } = React;

const App = () => {
  const [data, setData] = useState({
    user1: '',
    user2: '',
  });
  
  const onInputChange = event => {
    const newData = {...data };
    newData[event.target.name] = event.target.value;
    setData(newData);
  }
  
  return <div>
    <p><label htmlFor="user1">User 1</label><input id="user1" onChange={onInputChange} type="text" name="user1" value={data.user1} placeholder={'User 1'} /></p>
    <p><label htmlFor="user2">User 2</label><input id="user2" onChange={onInputChange} type="text" name="user2" value={data.user2} placeholder={'User 2'} /></p>
        <hr />
        <p><small>Debug State</small></p>
        <pre><code>{JSON.stringify(data, null, ' ')}</code></pre>
  </div>
  }
  ReactDOM.render(<App />, document.querySelector('#root'));
body {
font-family: Arial, sans-serif;
}

input {
  height: 50px;
  border-radius: 4px;
  padding: 0 12px;
  border: 1px solid #ccc;
}

code {
display: block;
background: #efefef;
padding: 20px;
}

label {
display: block;
font-size: 10px;
margin-bottom: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/axios@0.19.2/dist/axios.min.js"></script>

<div id="root"></div>

==== ОБНОВЛЕНИЕ 2 ====

const { useState } = React;

const App = () => {
  const [data, setData] = useState({ users: [{ value: ''}, { value: ''}]});
  
  const onInputChange = index => event => {
    const newData = {...data };
    newData.users[index].value = event.target.value;
    setData(newData);
  }
  
  return <div>
    {data.users.map((i, k) => <p key={`user-${k}`}><label htmlFor={`user-${k+1}`}>User {k + 1}</label><input id={`user-${k+1}`} onChange={onInputChange(k)} type="text" name={`user-${k+1}`} value={i.value} placeholder={`User ${k+1}`} /></p>)}
        <hr />
        <p><small>Debug State</small></p>
        <pre><code>{JSON.stringify(data, null, ' ')}</code></pre>
  </div>
  }
  ReactDOM.render(<App />, document.querySelector('#root'));
body {
font-family: Arial, sans-serif;
}

input {
  height: 50px;
  border-radius: 4px;
  padding: 0 12px;
  border: 1px solid #ccc;
}

code {
display: block;
background: #efefef;
padding: 20px;
}

label {
display: block;
font-size: 10px;
margin-bottom: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/axios@0.19.2/dist/axios.min.js"></script>

<div id="root"></div>
1
codingwithmanny 24 Июл 2020 в 22:17