javascript - 输入值正在被清空

标签 javascript reactjs

我在ReactJS中创建了一个简单的动态步骤表单,如果我在输入中键入某些内容,则只有第一个字符会存储在状态中,除非它由自动完成填充,但输入将为空,如果我继续表单然后再返回,前面的输入就被填满了。

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<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>
<script type="text/babel">
  // const { useState } = React
  function Step({ currentStep, step, children }) {
    if (currentStep !== step) return null
    return children
  }

  function StepForm({ attributesArray }) {
    const [datas, seDatas] = React.useState(attributesArray)

    const [currentStep, setCurrentStep] = React.useState(1)
    const [showMessage, setShowMessage] = React.useState(false)
    const [submitEnabled, setSubmitEnabled] = React.useState(false)

    function handleChange({ target }) {
      const { name, value, dataset: { index } } = target
      seDatas(prevState => {
        prevState[index] = { ...prevState[index], [name]: value }
        return prevState
      })
    }

    function submitDatas() {
      console.log(...datas)
    }

    function handleSubmit(e) {
      e.preventDefault()
      if (submitEnabled) {
        if (Object.values(datas).every(Boolean)) submitDatas()
        else setShowMessage(true)
      }
    }

    function _next() {
      const nextStep = currentStep >= 2 ? 2 : currentStep + 1
      if (nextStep === 2) setSubmitEnabled(true)
      setCurrentStep(nextStep)
    }

    function _prev() {
      // setSubmitEnabled(false)
      const prevStep = currentStep <= 1 ? 1 : currentStep - 1
      setCurrentStep(prevStep)
    }

    /*
    * the functions for our button
    */
    function previousButton() {
      if (currentStep !== 1) {
        return <a
          href='#previus'
          role='button'
          className='btn btn-secondary'
          onClick={_prev}>
          Previous
        </a>
      }
      return null
    }

    function nextButton() {
      if (currentStep < 2) {
        return <a
          href='#next'
          role='button'
          className='btn btn-primary'
          onClick={_next}>
          Next
        </a>
      }
      return null
    }

    return <>
      <p className='text-center'>Step {currentStep} </p>

      <form onSubmit={e => handleSubmit(e, submitEnabled)} className='mt-5'>
        {showMessage && <div className='alert alert-danger' role='alert'>Error.</div>}

        {
          datas.length && datas.map((each, step) => {
            return <Step currentStep={currentStep} step={step + 1} key={step}>
              {
                Object.keys(each).map((key, index) => {
                  return <div key={index} className='form-group'>
                    <label>{key}</label>
                    <input
                      className='form-control'
                      name={key}
                      type='text'
                      value={datas[step][key]}
                      data-index={step}
                      onChange={handleChange}
                    />
                  </div>
                })
              }
            </Step>
          })
        }
        <div className='btn-toolbar justify-content-between mt-5'>
          <div className='btn-group' role='group' aria-label='First group'>
            {previousButton()}
          </div>
          <div className='btn-group' role='group' aria-label='First group'>
            {currentStep === 2 ? <button className='btn btn-success btn-block'>Submit</button> : nextButton()}
          </div>
        </div>
      </form>
    </>
  }


  function App() {
    return <main className='page company-registration-page'>
      <section className='clean-block clean-form dark'>
        <div className='container'>
          <StepForm
            attributesArray={[{
              name: '',
              lastName: '',
              age: '',
              phone: ''
            },
            {
              zipCode: '',
              address: '',
              city: '',
              state: ''
            }]}
          />
        </div>
      </section>
    </main>
  }
  ReactDOM.render(<App />, document.getElementById('root'));
</script>

必须为示例工作提供最新的 Bapel。

最佳答案

您的代码正在更改状态引用变量。因此,当 React 将新状态与先前状态进行比较时,它们是相等的并且不会触发重新渲染。

您可以声明一个新变量,并使用 const newVar = [...prevState] 将 prevState 副本分配给它。这样你就可以只修改新变量 e 返回它,所以 React 将检测差异并正确重新渲染你的组件。

关于javascript - 输入值正在被清空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60636830/

相关文章:

Javascript:时间格式 HH:MM 的正则表达式

javascript - jQuery 菜单根本不起作用

reactjs - 使用自动绑定(bind)::运算符将参数传递给 react 函数

javascript - this.setState 不会覆盖旧状态?

javascript - React-Native 中的 Alt @decorators

javascript - AngularJS:在编写 HTML 之前等待上下文加载

javascript - 使用 jQuery/CSS 设置的鼠标光标在鼠标移动之前不会改变

javascript - 如何使用 NodeJS dokerode 库获取进程的输出?

javascript - ReactJS动态路由没有 "/"

javascript - React,循环对象,显示列表,并在选择时抓取该对象