简体   繁体   English

如何强制我的组件不重复使用相同的值?

[英]How can I force my components to not reuse the same values?

I have a React form where my users can fill their informations.我有一个 React 表单,我的用户可以在其中填写他们的信息。 Once it's done, they click submit and it brings them to the second part of the form.完成后,他们单击提交并将他们带到表单的第二部分。 However, there seems to be an issue since when I get on the second part of the form, it's already been filled with data from the previous form when it shouldn't...但是,似乎有一个问题,因为当我进入表单的第二部分时,它已经填充了前一个表单中不应该出现的数据......

I guess React does this to not have to re-render everytime, but it kinda bugs my application.我猜 React 这样做是为了不必每次都重新渲染,但它有点错误我的应用程序。

Here is the code for my Form and the Input.这是我的表单和输入的代码。 I didn't put all of the input since only the first 3 are concerned.我没有输入所有的输入,因为只有前 3 个是相关的。

How can I make sure that the data from the first render isn't reused on the second render?如何确保第一个渲染中的数据不会在第二个渲染中重复使用?

Thanks!谢谢!

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import FormTemplate from 'components/templates/FormTemplate';
import TextInput from 'components/forms/TextInput';
import Form from 'components/forms/Form';
import FormGroup from 'components/forms/FormGroup';
import TextareaInput from 'components/forms/TextareaInput';
import FileInput from 'components/forms/FileInput';
import { withTranslation } from 'react-i18next';
import Submit from 'components/forms/Submit';
import DropdownMultiple from 'components/forms/DropdownMultiple';
import { connect } from 'react-redux';
import instance from 'axiosInstance';
import { addErrors } from 'redux/actions';
import DropdownSingle from 'components/forms/DropdownSingle';
import { formToFormData } from 'utils';

export class SendApplication extends Component {
  constructor (props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.state = { interests: [], fieldsOfWork: [], salary: [], loading: true, stage: 1 };
  }

  handleSubmit (e) {
    e.preventDefault();
    this.setState({ loading: true });
    var fd = formToFormData(['email', 'first_name', 'last_name', 'phone_number', 'address', 'field_of_work', 'interests', 'salary_id', 'availability', 'job_type'], this.props.form);
    instance.post('/candidate', fd).then((success) => {
    }, (error) => {
      this.props.addErrors(error.response.data.errors, 'candidate-signup');
    }).then(() => {
      this.setState({ loading: false });
    });
  }

  componentDidMount () {
    instance.get('/candidate-data')
      .then((success) => {
        this.setState({
          loading: false,
          interests: success.data.interests,
          fieldsOfWork: success.data.fieldsOfWork,
          salary: success.data.salary,
          availability: success.data.availability,
          job_type: success.data.job_type
        });
      });
  }

  render () {
    return (
      <FormTemplate loading={this.state.loading} title={this.props.t('pages:sendApplication')}>
        {(this.state.stage === 1)
          ? <Form onSubmit={(e) => {
            e.preventDefault();
            this.setState({ stage: 2 });
          }} name="candidate-signup">
            <FormGroup>
              <TextInput name="first_name" />
              <TextInput name="last_name" />
            </FormGroup>
            <TextInput name="email" type="email" />
            <TextInput name="phone_number" />
            <TextInput name="address" />
            <DropdownMultiple name="field_of_work" options={this.state.fieldsOfWork} />
            <DropdownMultiple name="interests" options={this.state.interests}/>
            <DropdownSingle name="salary_id" options={this.state.salary} />
            <DropdownMultiple name="availability" options={this.state.availability} />
            <DropdownMultiple name="job_type" options={this.state.job_type} />
            <DropdownMultiple name="training"/>
            <DropdownMultiple name="work_experiences"/>
            <FileInput name="uploadCV" subtitle={this.props.t('uploadCVFormats')} accepted="pdf,docx" />
            <FileInput name="uploadVideoCV" subtitle={this.props.t('uploadVideoCVFormat')} required={false} />
            <Submit />
          </Form>
          : <Form onSubmit={this.handleSubmit} name="candidate-signup">
            <TextInput name="email" type="email" />
            <TextInput name="email_confirmation" type="email" />
            <TextInput name="password" />
            <TextInput name="password_confirmation" />
            <Submit />
          </Form>
        }

      </FormTemplate>
    );
  }
}

SendApplication.propTypes = {
  t: PropTypes.func.isRequired
};

SendApplication.defaultProps = {
  form: {}
};

const mapStateToProps = ({ input }) => {
  return {
    form: input['candidate-signup']
  };
};

export default connect(mapStateToProps, { addErrors })(withTranslation('common')(SendApplication));

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withTranslation } from 'react-i18next';
import { handleChange } from 'redux/actions';
import { connect } from 'react-redux';
import FormContext from 'context/FormContext';

export class TextInput extends Component {
  constructor (props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  getRequired () {
    if (this.props.required === true) {
      return <span className="tw-font-semibold tw-text-red-500 tw-text-sm tw-ml-2">{this.props.t('required')}</span>;
    }
  }

  handleChange (e, context) {
    var value = e.target.value;
    this.props.handleChange(this.props.name, value, context.name);
  }

  getValue (context) {
    if (this.props.input && this.props.input[context.name] && this.props.input[context.name][this.props.name]) {
      return this.props.input[context.name][this.props.name];
    } else {
      return undefined;
    }
  }

  render () {
    return (
      <FormContext.Consumer>
        {context =>
          <div className={`tw-flex tw-flex-col ${this.props.size} tw-px-2 tw-mb-3`}>
            <label htmlFor={this.props.name} className="tw-text-sm tw-font-bold">{this.props.title || this.props.t('common:' + this.props.name)}{this.getRequired()}</label>
            <input 
              value={this.getValue(context)}
              onChange={(e) => {
              this.handleChange(e, context);
            }} type={this.props.type} id={this.props.name} placeholder={this.props.title} className="focus:tw-outline-none focus:tw-shadow-outline tw-bg-gray-300 tw-rounded-lg tw-py-2 tw-px-3" />
            {this.props.errors && this.props.errors[context.name] && this.props.errors[context.name][this.props.name] && (
              <div className="tw-bg-red-100 tw-mt-2 tw-border-l-4 tw-border-red-500 tw-text-red-700 tw-p-2 tw-text-sm">
                <p>{this.props.errors[context.name][this.props.name]}</p>
              </div>
            )}

          </div>
        }
      </FormContext.Consumer>

    );
  }
}

TextInput.defaultProps = {
  size: 'w-full',
  required: true,
  type: 'text'
};

TextInput.propTypes = {
  name: PropTypes.string.isRequired,
  title: PropTypes.string,
  size: PropTypes.string.isRequired,
  required: PropTypes.bool,
  type: PropTypes.string,
  t: PropTypes.func.isRequired
};

const mapStateToProps = ({ errors, input }, ownProps) => {
  return {
    errors: errors,
    input: input
  };
};

export default connect(mapStateToProps, { handleChange })(withTranslation(['input'])(TextInput));

You can use the key to solve this problem.您可以使用密钥来解决此问题。
inside SendApplication component, add a prop key={this.state.stage} in FormTemplate , like thisSendApplication组件中,在FormTemplate添加一个 prop key={this.state.stage} ,像这样

<FormTemplate key={this.state.stage} loading={this.state.loading} title={this.props.t('pages:sendApplication')}>
// your rest of the code
</FormTemplate>

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

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