如何仅将一个数组保持在onChange状态

时间:2020-07-24 21:49:52

标签: reactjs react-hooks react-state

我有两个textField,我想用下面的setState函数更新我的状态。但是如果我console.log(state.users),它会继续生成数组。我只想要一个数组和更新的对象。

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

这是我的handlechange函数。

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)}

1 个答案:

答案 0 :(得分: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>