componentDidMount очищает значения в форме

#javascript #react-redux #redux-form

#javascript #реагировать-redux #переопределение формы

Вопрос:

Я использую библиотеку для определения города и штата на основе почтового индекса, введенного на экране-заставке. У меня есть значения, переданные на требуемую страницу, но я не могу поместить значение во входные данные формы.

Ранее я работал с этим, используя

 componentDidMount() {
  this.props.initialize({city: this.city, state:this.state, zipCode:this.zipCode });
}  
  

но это очистило бы значения в остальной части формы. Я попытался установить destroyOnUnmount в false и forceUnregisterOnUnmount в true и все равно очистил бы значения. Я не уверен, куда двигаться дальше с этим без реструктуризации формы redux. Мой код:

CarObjectInfo.js

 import vinDecoder from 'vin-decode';

export const getCarYear = (vinNumber) =>{
   var carYear;
   var carObject = vinDecoder(vinNumber).decode();
   return carYear = carObject['year'];

};
  

Address.js

 import React, { Fragment, Component} from 'react';
import { Field, reduxForm, formValueSelector } from 'redux-form';
import RenderField from './fields/RenderField'; 
import zipField from './fields/zipField';
import { ZipCodeValidator, validZipCode} from '../../helpers/form_validators/ZipCodeValidator';
import {GeneralFieldValidators, requiredStreetAddress, validStreetAddress, requiredCity, validCity} from '../../helpers/form_validators/GeneralFieldValidators'
import { Progress } from 'reactstrap';
import {connect} from 'react-redux';


const renderError = ({ meta: { touched, error } }) =>
  touched amp;amp; error ? <span>{error}</span> : false;


   const state = ['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 
   'FL', 'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 
   'MD', 'MA', 'MI', 'MS', 'MO', 'MT',
   'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 
   'PA', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 
   'WI', 'WY'];
   const renderStateSelector = ({ input, label, type, meta: { 
   touched, error } }) => (
   <Fragment>
     <label htmlFor={label}>{label}</label>
       <div>
        <select {...input} type={type} className="form-control">
          <option value=""></option>
            {state.map(val => <option value={val} key={val}>{val} . 
          </option>)}
         </select>
         {touched amp;amp; error amp;amp; <span className="errorMessage">{error} . 
        </span>}
       </div>
     </Fragment>
 );
 const requiredState = value => value ? undefined : 'Please provide a 
 state'

 class Address extends Component{
   constructor(props){
    super(props)
    this.handleSubmit = this.props.handleSubmit;
    this.previousPage = this.props.previousPage;
    this.zipCode = this.props.zipCode;
    this.city = getCity(this.zipCode);
   }

   render (){
    const {handleSubmit, previousPage, firstName, zipCode, city} = 
     this.props;

  return (
<Fragment>
  <Logo />
  {/*Fragment is equivalent to wrapping it all up in a div */}
  <div className="container">
  <div className="box">
    <div className="row">
      <div className="col-lg-12 col-sm-12 text-center">
        <br />
          <div>
            <Progress animated value="33">33%</Progress>

        </div>
        <br/>
        <span className="title text-center">Step 2 of 6</span>
        <h2 className="text-center">Address</h2>
         </div>
    </div>

    <form className="form" onSubmit={handleSubmit}>
      <hr />
      <b className="formHeading"><i className='fa fa-home'></i> Hey {firstName}, what's your home address?</b>
      <br />
      <br />
      <div className="col-md-6 mx-auto">
        <Field name="streetAddress" type="text" component={RenderField} label="Street Address" validate={[requiredStreetAddress, validStreetAddress]} />
        <br />
      </div>
      <div className="col-md-6 mx-auto">
        <Field name="aptUnit" type="text" component={RenderField} label="Apt/Unit" />
        <br />
      </div>
      <div className="col-md-6 mx-auto">
      <div className="form-row">
      <div className="col-md-8">
      <Field name="city" type="text" component={RenderField} readonly="true" label="City"  validate={[requiredCity, validCity]} />
      </div>
      <div className="col-md-4">
      <Field name="state" type="text" component={renderStateSelector} label="State" validate={requiredState} />
        <br />
      </div>
      </div>
      </div>
      <div className="col-md-6 mx-auto">
        <Field name="zipCode" type="text" value={zipCode} component={zipField} readonly="true" label="Zip Code"  validate={validZipCode} />
        <br />
      </div>
       <form previousPage={this.props.previousPage}>
        <button type="submit" id="nextBtn" className="btn btn-primary form-control">Next</button>
        <button type="submit" id="backBtn" onClick={previousPage} className="btn btn-light form-control">Back</button>
        <br />       
        </form>
      {/*End of Form */}
    </form>
    </div>
    <Footer />
  </div>

</Fragment>

);
}
}



Address = reduxForm({
 form: 'insurance',
 destroyOnUnmount: false,
 forceUnregisterOnUnmount: true,
})(Address);

const selector = formValueSelector('insurance') 

Address = connect(state => {

 const zipCode = selector(state, 'zipCode');
 const firstName = selector(state, 'firstName');

 return {
  zipCode,
  firstName,
  city   
 }

 })(Address)

 export default Address;
  

Я очень новичок в react, поэтому пытаюсь учиться по ходу дела

Комментарии:

1. Пара советов: используйте функции со стрелками, чтобы вам не приходилось напрямую связывать функции, а Fragment также можно записать как <> и </> . Добавлен тег «redux-form», чтобы знакомым людям было легче найти ваш вопрос

2. Я бы ответил на ваш вопрос, но я болен, и у меня недостаточно внимания, чтобы полностью распутать это… но похоже, что свойство defaultProps — это, вероятно, то, что вы ищете.

Ответ №1:

При вызове initialize поведение по умолчанию redux-form заключается в очистке формы и инициализации только тех значений, которые вы туда передаете. Чтобы сохранить другие значения, вам нужно использовать свойство keepDirtyOnReinitialize: true и enableReinitialize: true

Кстати, насколько я вижу, вам не нужно вызывать initialize на componentDidMount . Вы можете передать в свою форму (что означает возврат свойства из mapStateToProps ), которая вызывается initialValues , заполненную city, zip, FirstName…

Дополнительная информация приведена в документах API по reduxForm ссылке