简体   繁体   English

React Form 不更新状态 onChange

[英]React Form not updating state onChange

I'm trying to practice React forms, and I can't seem to solve this error.我正在尝试练习 React 表单,但似乎无法解决此错误。 I've developed a multi-input form and I need the value to update the parent's state.我开发了一个多输入表单,我需要该值来更新父级的状态。 When I start typing in the input field it triggers the Switch case default.当我开始在输入字段中输入时,它会触发 Switch case 默认值。 I'm not sure if maybe I'm typing the 'handleChange' function wrong or if I should have a separate state for the state.data.我不确定我是否输入了错误的“handleChange”函数,或者我是否应该为 state.data 设置一个单独的状态。 Any advice would be much appreciated任何建议将不胜感激

import React, { useState } from 'react';
import Form from './Form';
import Results from './Results';

function App() {
    const [state, setState] = useState({
        data: 1,
        Name: '',
        Email: '',
        City: ''
    });

    const nextStep = () => {
        setState({
            data: state.data + 1
        });
  };

  const handleChange = e => {
        let field = e.target.name;
        let val = e.target.value;
        setState({ [field]: val });
    };

    switch (state.data) {
        case 1:
            return (
                <div className='App-container'>
                    <Form
                        button='Next'
                        nextStep={nextStep}
                        name='Name'
                        state={state.name}
                        handleChange={handleChange}
                    />
                </div>
            );
        case 2:
            return (
                <div className='App-container'>
                    <Form
                        button='Next'
                        nextStep={nextStep}
                        name='Email'
                        state={state.email}
                        handleChange={handleChange}
                    />
                </div>
            );
        case 3:
            return (
                <div className='App-container'>
                    <Form
                        button='Submit'
                        nextStep={nextStep}
                        name='City'
                        state={state.city}
                        handleChange={handleChange}
                    />
                </div>
            );
        case 4:
            return (
                <div className='App-container'>
                    <Results data={state} />
                </div>
            );
        default:
            return 'Error';
    }
}

export default App;

import React from 'react';

const Form = ({ button, nextStep, name, state, handleChange }) => {
    const handleSubmit = e => {
        e.preventDefault();
        nextStep();
    };

    return (
        <div className='Form-container'>
            <form onSubmit={handleSubmit}>
                <input
                    type='text'
                    placeholder={name}
                    name={name}
                    value={state}
                    onChange={handleChange}
                />
                <input type='submit' value={button} />
            </form>
        </div>
    );
};

export default Form;


import React from 'react';

const Results = ({ data }) => {
    return (
        <div>
            <h1>Info</h1>
            <p>{data.name}</p>
            <p>{data.email}</p>
            <p>{data.city}</p>
        </div>
    );
};

export default Results;

You losing state on handleChange while expecting it to merge with the current one, but it is not how useState works in contradiction to this.setState in class components:你失去状态handleChange同时期待它与当前的合并,但它不是如何useState工作在矛盾this.setState类组件:

// Results new state: { data };
setState({ data: state.data + 1 });

// Instead update the copy of the state.
// Results new state: { data, Name, Email, City }
setState({ ...state, data: state.data + 1 });

Check useState note in docs :检查文档中的useState注释

Note笔记

Unlike the setState method found in class components, useState does not automatically merge update objects.与类组件中的 setState 方法不同,useState 不会自动合并更新对象。 You can replicate this behavior by combining the function updater form with object spread syntax.您可以通过将函数更新程序形式与对象传播语法相结合来复制此行为。

Another option is useReducer, which is more suited for managing state objects that contain multiple sub-values.另一种选择是 useReducer,它更适合管理包含多个子值的状态对象。

I recommend using a custom hook for form inputs.like follows我建议对表单输入使用自定义钩子。如下所示

//useForm.js

const useForm = defaultValues => {
  const [values, setValues] = useState(defaultValues);
  const handleChange = ({ name, value }) => {
    setValues(prevState => ({ ...values, [name]: value }));
  };
  const reset = () => {
    setValues(null);
  };
  return [values, handleChange, reset];
};

inside component内部组件

 const [formValues, handleChange, resetForm] = useForm();

 return (
    <>
     <Input
       value={formValues.name}
        onChange: str => handleChange({ name: "name", value: str })
      />

     <Input
       value={formValues.email}
        onChange: str => handleChange({ name: "email", value: str })
      />
    </>
  )

You need to spared old state你需要避免旧状态

  const handleChange = e => {
        let field = e.target.name;
        let val = e.target.value;
        setState({ ...state, [field]: val });
    };

this is setState({ ...state, [field]: val });这是setState({ ...state, [field]: val });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM