简体   繁体   English

如何阻止 State object 在 React js 中更新输入字段的 onChange

[英]How to stop State object from updating with onChange of an input field in React js

I am trying to create a multi step register form for my app.我正在尝试为我的应用程序创建一个多步骤注册表单。 I am saving form data to a "registerData" state.我正在将表单数据保存到“registerData”state。

I have a problem with inputting data.我在输入数据时遇到问题。 Whenever I try to input data in one of the component pages (for example page1, Name), it does the onChange and changes the Name from "" to inputted letter but immediately after that it reverts "registerData" to its original state with all properties set to "".每当我尝试在其中一个组件页面(例如 page1,Name)中输入数据时,它都会执行 onChange 并将名称从“”更改为输入的字母,但之后它会立即将“registerData”恢复为具有所有属性的原始 state调成 ””。

Here is the code:这是代码:

Register.js:注册.js:

import React, {useState} from 'react';
import Page1 from './register_components/Page1';
import Page2 from './register_components/Page2';
import Page3 from './register_components/Page3';

function Register() {
  const [registerData, setRegisterData] = useState(
    {
      //Personal Details
      Name: "",
      LastName: "",
      Phone: "", //Null
      Birthday: "", //Null
      //Address
      Street: "",
      Zip: "",
      Building: "",
      House: "", //Null
      City: "",
      Voivodeship: "",
      //Login information
      Email: "",
      Password: ""
    }
  ) 


  const [ pageIndex, setPageIndex] = useState(0)
  const [ pages, setPages ] = useState([
    <Page1 registerData={registerData} setRegisterData={(data) => {setRegisterData(data)}}/>,
    <Page2 registerData={registerData} setRegisterData={(data) => {setRegisterData(data)}}/>,
    <Page3 registerData={registerData} setRegisterData={(data) => {setRegisterData(data)}}/>
  ])

  const PrevPage = () =>{
    if (pageIndex <= 0)
      return
    setPageIndex(pageIndex - 1)
  }

  const HandleSubmit = (event) => {
    event.preventDefault();
    if (pageIndex !== pages.length - 1){
      setPageIndex(pageIndex + 1)
      return
    }

    console.log("Submmited")
  }

  return (
    <div className="App">
      <h1>Rejestracja</h1>

      <form className='register-form' onSubmit={HandleSubmit}>
        {pages[pageIndex]}
        {pageIndex !== 0 && <button type="button" onClick={ () => {PrevPage()}}>Poprzedni</button>}
        <button type="submit">{pageIndex !== pages.length - 1? "Nastepny" : "Przeslij"}</button>
      </form>

    </div>
  );
}


export default Register;

Page1.js Page1.js

import React from 'react'

export default function Page1({registerData, setRegisterData}) {
    console.log("rerender")
    console.log(registerData)
  return (
    <div>
        <input
            placeholder='Imie'
            required type='text'
            value={registerData.Name}
            onChange={(e) => { setRegisterData({...registerData, Name: e.target.value}); console.log(e.target.value) }}
        />
        
        <input
            placeholder='Nazwisko'
            required
            type='text'
            value={registerData.LastName}
            onChange={(e) => { setRegisterData({...registerData, LastName: e.target.value}) }}
        />
        
        <input
            placeholder='Nr telefonu'
            required
            type='text'
            value={registerData.Phone}
            onChange={(e) => { setRegisterData({...registerData, Phone: e.target.value}) }}
        />
        
        <div className='date-form'>
            <label>Data urodzenia</label>
            <input
                type='date'
                value={registerData.Date}
                onChange={e => { setRegisterData({...registerData, Birthday: e.target.value}) }}
            />
        </div>
    </div>
  )
}

As I don't have much experience with react, it's hard for me to tell but I think the problem lays in the Register.js rerendering with each change to the "registerData" state which causes it to revert to its original values.由于我没有太多的反应经验,所以我很难说,但我认为问题出在 Register.js 每次更改“registerData”state 时都会重新呈现,这会导致它恢复为原始值。

Try this as a function for onChange values... It helps you a lot.试试这个作为 onChange 值的 function ...它对你有很大帮助。 Secondly, in you input tag add the name attribute with the same state object names.其次,在您输入的标签中添加具有相同 state object 名称的名称属性。

For Example:例如:

    const [registerData, setRegisterData] = useState(
{
    //Personal Details
    Name: "",
    LastName: "",
    Phone: "", //Null
    Birthday: "", //Null
    //Address
    Street: "",
    Zip: "",
    Building: "",
    House: "", //Null
    City: "",
    Voivodeship: "",
    //Login information
     Email: "",
     Password: ""
   }
 ) 


  const handleFormChange = (index, event) => {
   let data = [...inputFields];
   data[index][event.target.name] = event.target.value;
   setInputFields(data);
 };

<div>
      <input
          placeholder='Imie'
          required type='text'
          name="Name"
          value={registerData.Name}
          onChange={(event) => handleFormChange(index, event)}
      />
    
    <input
        placeholder='Nazwisko'
        required
        type='text'
            name="LastName"
            value={registerData.LastName}
           onChange={(event) => handleFormChange(index, event)}
      />
    
   
      </div>
  </div>

You shouldn't store JSX in state. Your pages state isn't a state value, as it can be calculated by other state values in this case ( pageIndex ).您不应该将 JSX 存储在 state 中。您的pages state 不是 state 值,因为在这种情况下它可以由其他 state 值计算( pageIndex )。 Another thing that hints that it shouldn't be a state value is that you're never using setPages() .暗示它不应该是 state 值的另一件事是您从不使用setPages() Instead, you can make this a regular object:相反,您可以将其设为常规 object:

const pages = [
  <Page1 registerData={registerData} setRegisterData={(data) => {setRegisterData(data)}} />,
  <Page2 registerData={registerData} setRegisterData={(data) => {setRegisterData(data)}} />,
  <Page3 registerData={registerData} setRegisterData={(data) => {setRegisterData(data)}} />
];

I would also consider putting the above into its own component called Page which accepts a page number as an index and then uses that number in a simple if-statement to decide which page component ( Page1 , Page2 , Page3 ) to render.我还会考虑将上面的内容放入它自己的名为Page的组件中,该组件接受页码作为索引,然后在简单的 if 语句中使用该页码来决定要呈现哪个页面组件( Page1Page2Page3 )。

So, why does making pages a regular object instead of a state value fix this issue?那么,为什么将pages设置为常规 object 而不是 state 值可以解决此问题? Each time your Register component rerenders, the code within Register runs, causing the line with useState() to execute again:每次您的Register组件重新呈现时, Register中的代码都会运行,导致带有useState()的行再次执行:

const [pages, setPages] = useState(/* initival value */ [...])

The "initial value" argument that you pass to useState() is ignored after the initial render, so while the "initial value" gets evaluated each time your component rerenders, it gets ignored and the value of pages doesn't change, only using setPages() can change pages .您传递给useState()的“初始值”参数在初始渲染后会被忽略,因此当每次组件重新渲染时“初始值”都会被评估,它会被忽略并且pages的值不会改变,仅使用setPages()可以改变pages This results in pages storing an array of object references that represent your JSX on the initial mount of your component.这会导致pages存储一个 object 引用数组,这些引用代表组件初始挂载时的 JSX。 That means that on subsequent rerenders of your component, pages[pageIndex] will always return the same JSX object reference, and as it's the same on every rerender, React won't rerender this component.这意味着在组件的后续重新渲染中, pages[pageIndex]将始终返回相同的 JSX object 引用,并且在每次重新渲染时都是相同的,React 不会重新渲染该组件。

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

相关问题 react-modal - onChange 输入未更新 state - react-modal - onChange on input is not updating state 反应:onChange不会将值更新为输入字段 - React: onChange not updating value to input field React.JS Typescript - OnChange 表示状态对象的“组件正在将类型文本的受控输入更改为在 OnChange 中不受控制” - React.JS Typescript - OnChange says "A component is changing a controlled input of type text to be uncontrolled in OnChange" for State Object 反应 onChange 不更新状态 - React onChange not updating state 如何在REACT JS中为onChange事件更新JSON对象的状态? - How to Update JSON Object's state for onChange event in REACT JS? 如何阻止我的 React 应用程序根据输入字段不断更新元素? - How do I stop my React application from continuously updating an element based on an input field? onChange object in state in React - onChange object in state in React React Form 不更新状态 onChange - React Form not updating state onChange 如何在更新输入字段时隐藏 React Js 中的验证错误? - How to hide validation error in React Js upon updating the input field? React JS:祖父组件的 setState 方法不会更新孙子输入字段 onChange 事件单击的状态 - React JS : grandparent component's setState method doesn't update state of a grandchild input field onChange event click
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM