Je suis relativement nouveau dans React et Redux, et j'ai créé un simple formulaire de courrier électronique ajax pour apprendre. Le problème que je rencontre est qu'après la soumission du formulaire, je redéfinis l'état du magasin sur Initialstate, ce qui devrait effacer tous les champs, mais ce n'est pas le cas. Je peux voir les changements de magasin dans Redux Logger, * voir l'image ci-jointe mais ces changements ne s'affichent pas sur l'interface utilisateur. Mon magasin ne correspond-il pas à l'état correctement? Ou est-ce que je mute un état quelque part?

Mon réducteur ressemble à ceci:

export default function contactForm(state = initialState.formValues, action) {
  switch (action.type) {
    case types.FORM_RESET:
      return initialState.formValues;
    case types.FORM_SUBMIT_SUCCESS:
      return Object.assign({}, action.message);
    default:
      return state;
  }
}

Combinez les réducteurs:

import { combineReducers } from 'redux';
import message from './formReducer';
import ajaxCallsInProgress from './ajaxStatusReducer';

const rootReducer = combineReducers({
  message,
  ajaxCallsInProgress
});

Mon état initial ressemble à:

export default {
  formValues: {
    name: '', email: '', message: '',
  },
  ajaxCallsInProgress: 0,
};

Mes actions ressemblent à ceci:

export function messageSuccess(message) {
  return { type: types.FORM_SUBMIT_SUCCESS, message };
}

export function resetForm() {
  return { type: types.FORM_RESET };
}

export function saveMessage(message) {
  return function (dispatch) {
    dispatch(beginAjaxCall());
    return messageApi.saveMessage(message)
    .then(() => {
      dispatch(messageSuccess(message));
      dispatch(resetForm());
    }).catch((error) => {
      dispatch(ajaxCallError(error));
      throw (error);
    });
  }
}

Dans la vue, je mappe l'état aux accessoires via:

constructor(props, context) {
  super(props, context);
  this.state = {
   message: Object.assign({}, this.props.message),
  }
}

render() {
  return (
    <ContactForm
      onChange={this.updateMessageState}
      onSubmit={this.submitForm}
      message={this.state.message}
    />
  );
}

function mapStateToProps(state) {
  return {
   message: state.message,
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(formActions, dispatch)
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(ContactSection);

Journal montrant les modifications du magasin

enter image description here

Je serais très reconnaissant de tout conseil.

1
Graeme Paul 16 janv. 2017 à 13:51

2 réponses

Meilleure réponse

J'ai ajouté ce qui suit qui a mis à jour l'état. Je ne sais pas si c'est la meilleure pratique avec Redux, mais cela a fonctionné

componentWillReceiveProps(nextProps) {
    this.setState({ message: nextProps.mail });
  }
0
Graeme Paul 30 janv. 2017 à 13:45

J'ai mis à jour ma réponse avec le code qui, à mon avis, devrait fonctionner pour votre exemple. Vous étiez assez proche, mais sur la base de vos commentaires sur la tentative de combiner deux réducteurs, j'ai créé deux réducteurs pour que vous puissiez voir comment cela fonctionne.

/* constants.js */
export default {
  FORM_RESET: 'FORM_RESET',
  FORM_SUBMIT: 'FORM_SUBMIT',
  AJAX_REQUEST: 'AJAX_REQUEST'
};


/* form-values-reducer.js */
const initialState = {
  name: '',
  email: '',
  message: ''
};

export default const formValuesReducer = (state = initialState, action) => {
  switch (action.type) {
    case Constants.FORM_SUBMIT:
      return {
        ...state,
        message: action.message
      };

    case Constants.FORM_RESET:
      return {
        ..state,
        name: '',
        email: '',
        message: ''
      };

    default:
      return state;
  }
};

/* ajax-request-reducer.js */
const initialState = {
  ajaxRequestCount: 0
};

export default const ajaxRequestReducer = (state = initialState, action) => {
  switch (action.type) {
    case Constants.AJAX_REQUEST:
      return {
        ...state,
        ajaxRequestCount: state.ajaxRequestCount + 1
      };
    default:
      return state;
  }
};

/* action-creators.js */
export const resettedForm = () => {
  return {
    type: Constants.FORM_RESET
  }
};

export const submittedForm = (message) => {
  return {
    type: Constants.FORM_SUBMIT,
    message
  }
};

export const ajaxRequested = () => {
  return {
    type: Constants.AJAX_REQUEST
  }
};

/* actions */
export const resetForm = (dispatch) => {
  return () => {
    dispatch(resettedForm());
  }
};

export const submitForm = (dispatch) => {
  return (message) => {
    dispatch(ajaxRequested());
    dispatch(submittedForm(message));
  }
};

/* reducers.js */
import { combineReducers } from 'redux';
import ajaxRequest from './ajax-request-reducer';
import formValues from './form-values-reducer';

export default combineReducers({
  ajaxRequest,
  formValues
});

/* Component */
import React from 'react';
import { connect } from 'react-redux';
import { resetForm, submitForm } from './actions';

const App = (props) => (
  <div>Your app UI stuff goes here</div>
);

const mapStateToProps = (state) => {
  return {
    name: state.formValues.name,
    email: state.formValues.email,
    message: state.formValues.message,
    ajaxRequestCount: state.ajaxRequest.ajaxRequestCount
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    resetForm: resetForm(dispatch),
    submitForm: submitForm(dispatch)
  }
};

export default connect(mapStateToProps, mapDispatchToProps)(App);

Je n'ai parcouru rien de tout cela, il peut donc y avoir des erreurs dans le code ici et là.

2
Tom 24 janv. 2017 à 08:42