在反应挂钩中更新嵌套对象

时间:2019-11-16 09:04:18

标签: javascript reactjs

我目前正在尝试实现动态+多步骤表单,并且想知道如何在地图中更新地图的值。

例如:我有三个字段“名字”,“姓氏”,“电子邮件”。我想存储在“常规”项中的名称值,而我想存储在“联系”项中的电子邮件值。 目前,我已经实现了一种称为 onChange 的方法,该方法被赋予每个字段并监听更改并将该字段及其值存储在状态中。

function App() {
  const [state, setState] = useState(false);

  const onChange = (field, value) => {
    console.log("Values:", value);

    setState({
      ...state,
      [field]: value
    });

    console.log("State:", state);
  };

  return (
    <div className="App">
      <EuiForm>
        <EuiFormRow label="First Name">
          <EuiFieldText
            name="first"
            onChange={event => onChange("firstName", event.target.value)}
          />
        </EuiFormRow>
        <EuiSpacer />

        <EuiFormRow label="Last Name">
          <EuiFieldText
            name="last"
            onChange={event => onChange("lastName", event.target.value)}
          />
        </EuiFormRow>
        <EuiSpacer />

        <EuiFormRow label="Email">
          <EuiFieldText
            name="email"
            onChange={event => onChange("email", event.target.value)}
          />
        </EuiFormRow>
        <EuiSpacer />

        <EuiButton type="submit" fill>
          Save form
        </EuiButton>
      </EuiForm>
    </div>
  );
}

什么是更新值以使我的状态数据看起来像这样的正确方法?

{
  "general": {
    "firstName": "ABCD",
    "lastName": "EFGH"
  },
  "contact": {
    "email": "abcd@efgh.com"
  }
}

2 个答案:

答案 0 :(得分:0)

最初将状态设为object,就像这样

const [state, setState] = useState({ general :{}, contact:{});

比做这样的事情

const onChange = (field, value) => {
    var temp = {...state}
   if(field == 'firstName'){
      temp.general.firstName = value
      setState({
      ...state,
      general:temp
    });
   } else if(field == 'lastName'){
      temp.general.lastName= value
      setState({
      ...state,
      general:temp
    });
   } else if(field == 'email'){
      temp.contact.email= value
      setState({
      ...state,
      contact:temp
    });
   }

    console.log("State:", state);// this will not work as the setState is asynchronous


};


  // so you can view the state like this 
 useEffect(() => {
     console.log('State', state);  // so this block of code will watch for any changes in state
  }, [state]);

答案 1 :(得分:0)

为简化起见,您可以定义两个不同的状态,然后在提交时合并它们。这是一个示例:

function App() {
  const [general, setGeneral] = React.useState({});
  const [contact, setContact] = React.useState({});
  
  const onChange = (set, field, value) => {
    set(state => ({
      ...state,
      [field]: value
    }));
  };
  
  const onSubmit = (e) => {
    e.preventDefault();
    console.log({
      general,
      contact
    });
  }
  
  return (
    <div className="App">
      <form onSubmit={onSubmit}>
        <label htmlFor="First Name">First Name
          <input
            name="first"
            onChange={event => onChange(setGeneral, "firstName", event.target.value)}
          />
        </label>
        <hr />

        <label htmlFor="Last Name">Last Name
          <input
            name="last"
            onChange={event => onChange(setGeneral, "lastName", event.target.value)}
          />
        </label>
        <hr />

        <label htmlFor="Email">Email
          <input
            name="email"
            onChange={event => onChange(setContact, "email", event.target.value)}
          />
        </label>
        <hr />

        <button type="submit">
          Save form
        </button>
      </form>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>