我在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用于示例工作。
答案 0 :(得分:1)
您的代码正在更改状态参考变量。因此,当React将新状态与prevState进行比较时,它们是相等的,并且不会阻碍渲染。
您可以声明一个新变量,并使用const newVar = [...prevState]
将prevState副本分配给它。这样,您只能修改新变量e使其返回,因此React将检测到diff并正确地重新呈现您的组件。