Состояние редукции порта к состоянию компонента при монтировании компонента (без необходимости запроса GET) - PullRequest
0 голосов
/ 24 февраля 2019

У меня есть форма в приложении React / Redux, которая используется для обновления информации - следовательно, необходимо предварительно заполнить поля текущими данными.

Перед монтированием компонента данные для формыуже находится в состоянии Redux.

В настоящее время в жизненном цикле componentDidMount() отправляется запрос axios GET, чтобы снова получить информацию из базы данных и загрузить ее в состояние избыточности.

Этот метод работает нормально, однако я бы хотел избежать дополнительного / избыточного запроса GET, поскольку информация уже находится в состоянии избыточности.

Как перенести состояние избыточности в состояние компонента при его загрузке, чтобыполя ввода заполнены (без необходимости запроса GET)?

код компонента указан ниже.

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import Navbar from '../components/layout/Navbar';
import Sidebar from '../components/layout/Sidebar';
import Breadcrumbs from '../components/layout/Breadcrumbs';
import TextFieldGroup from '../components/form-components/TextFieldGroup';

import { getPatientById } from '../redux/actions/patient.actions';

class PatientEdit extends Component {
  constructor() {
    super();
    this.state = {
      firstName: '',
      lastName: '',
      errors: {}
    };
  }

  componentDidMount = () => {
    if (this.props.match.params.patient_id) {
      this.props.getPatientById(this.props.match.params.patient_id);
    }
  };

  componentWillReceiveProps = nextProps => {
    if (nextProps.errors) {
      this.setState({ errors: nextProps.errors });
    }

    if (nextProps.patients.patient) {
      const patient = nextProps.patients.patient;
      this.setState({
        firstName: patient.firstName.patients,
        lastName: patient.lastName.patients
      });
    }
  };

  onChange = e => {
    this.setState({ [e.target.name]: e.target.value });
  };

  onSubmit = (e, patient_id) => {
    e.preventDefault();
    // boring script to handle form submission...
  };

  render() {
    const { errors } = this.state;
    const { patient } = this.props.patients;

    return (
      <>
        <Navbar />
        <div className="app-body">
          <Sidebar />
          <main className="main">
            <div className="container">
              <form onSubmit={e => this.onSubmit(e, patient._id)}>
                <div>
                  <input
                    type="text"
                    name="firstName"
                    value={this.state.firstName}
                    onChange={this.onChange}
                  />
                  <input
                    type="text"
                    name="lastName"
                    value={this.state.lastName}
                    onChange={this.onChange}
                  />
                </div>
                <div>
                  <Link to="/patients" className="btn btn-light mr-2">
                    Cancel
                  </Link>
                  <button type="submit" className="btn btn-primary">
                    Submit
                  </button>
                </div>
              </form>
            </div>
          </main>
        </div>
      </>
    );
  }
}

PatientEdit.propTypes = {
  getPatientById: PropTypes.func.isRequired,
  patients: PropTypes.object.isRequired,
  errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  patients: state.patients,
  errors: state.errors
});

export default connect(
  mapStateToProps,
  { getPatientById }
)(PatientEdit);

действие getPatientById

export const getPatientById = id => dispatch => {
  dispatch(setPatientLoading());
  axios
    .get(`/api/patients/${id}`)
    .then(res => {
      dispatch({
        type: GET_PATIENTS_SINGLE,
        payload: res.data
      });
    })
    .catch(err => {
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      });
    });
};

Ответы [ 2 ]

0 голосов
/ 24 февраля 2019

Не могли бы вы передать состояние Redux и использовать его для логики управления?Я предполагаю, что это происходит из patients состояния Redux, поскольку вы используете его в методе жизненного цикла componentWillReceiveProps, поэтому, если это так, вы не могли бы сделать:

// rest of code emitted for brevity
componentDidMount = () => {
    // assuming init state for patients.patient is null
    if (!this.patients.patient && this.props.match.params.patient_id) {
      this.props.getPatientById(this.props.match.params.patient_id);
    }
  };

Это предполагает this.props.patients.patient начальное состояние null от редуктора.Если вместо этого this.props.patients равно нулю, то измените управляющий логический код на !this.props.patients && this.props.match.params.patient_id.

Управляющая логика здесь гласит: «Если пациенты нулевые и у нас есть идентификатор параметра, сделайте вызов API GET»,Если у вас уже есть пациент, это не будет беспокоить.

0 голосов
/ 24 февраля 2019

Похоже, вы копируете данные из избыточного в локальное состояние.Это может быть необходимо или нет.Что касается вашей цели, то почему бы не сделать напрямую данные, полученные из Redux (без их копирования в состояние)?В этом случае вы можете пропустить вызов axios в componentDidMount.

Если вы все равно хотите, чтобы данные из Redux находились в состоянии, вы можете скопировать их в состояние в конструкторе или в componentDidMount.Это делает копию только один раз, хотя.Если затем вам нужно синхронизировать данные из редукции и состояния, вам нужно убедиться в этом в componentWillReceiveProps.

Я полагаю, что проблема, с которой вы столкнулись при текущей настройке, заключается в том, что componentWillReceiveProps не вызывается для первого рендеринга, поэтому ничего не было скопировано в ваше состояние.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...