2017-10-12 1 views
0

Je fais la liste de téléphone en utilisant React et Redux, et ai le problème. Ce à quoi il faut s'attendre: l'utilisateur met ses données sous forme modale et quand il clique sur le bouton Soumettre - onClick déclenche les déclenchements de fonction et de données vers le magasin Redux, et après le magasin vers localStorage, où toutes les données seront stockées. Le problème: au lieu de créer un tableau avec un objet contenant des données en mémoire, le tableau vide a été créé. Après avoir cliqué sur le bouton Envoyer, les données du premier clic sont remplacées par celles du tableau vide. Et ainsi de suite.Réagir + Redux ne met pas à jour le magasin

J'ai eu le même problème avec la version standard de setState.

Le code:

App:

import React from "react"; 
import { Input } from "../components/Input"; 
import { Table } from "../components/Table"; 
import { ButtonAdd } from "../components/ButtonAdd"; 
import { connect } from "react-redux"; 
import { setInput, setUser, setFormModalStatus, setSuccessModalStatus} from 
"../actions/dataActions"; 

class App extends React.Component { 

constructor(props) { 
    super(props); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    this.openFormModal = this.openFormModal.bind(this); 
    this.closeFormModal = this.closeFormModal.bind(this); 
    this.openSuccessModal = this.openSuccessModal.bind(this); 
    this.closeSuccessModal = this.closeSuccessModal.bind(this); 
} 

openFormModal() { 
    this.props.setFormModalStatus(true); 
} 

closeFormModal() { 
    this.props.setFormModalStatus(false); 
} 

openSuccessModal() { 
    this.props.setSuccessModalStatus(true); 
} 

closeSuccessModal() { 
    this.props.setSuccessModalStatus(false); 
} 

handleSubmit(e) { 
    this.closeFormModal(); 
    this.openSuccessModal(); //this is for modals 

    const datas = this.props.form.input.values //{name: 'Rick', tel: 12345} 
    this.props.setUser(datas); //making dispatch with data 

    console.log(this.props.data.users); // [] - the issue 

    const testData = {name: Josh, tel: 54321}; 
    this.props.setUser(testData); 

    console.log(this.props.data.users); //[{name: 'Rick, tel: 12345}] 

    e.preventDefault(); 
    this.props.form.input.values = ''; 
} 
render() { 
    return (
     <div className="container"> 
      <div className="row"> 
       <div className="col-xs-12 col-md-10 col-md-offset-1"> 
        <div className="box"> 
         <Input input={this.props.input}/> 
         <ButtonAdd 
          formModalStatus= 
{this.props.data.formModalStatus} 
          successModalStatus= 
{this.props.data.successModalStatus} 
          openFormModal={this.openFormModal} 
          closeFormModal={this.closeFormModal} 
          closeSuccessModal={this.closeSuccessModal} 
          handleSubmit={this.handleSubmit} 
         /> 
        </div> 
        <Table /> 
       </div> 
      </div> 
     </div> 
     ); 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
     data: state.data, 
     form: state.form 
    }; 
    }; 

const mapDispatchToProps = (dispatch) => { 
    return { 
     setInput: (input) => { 
      dispatch(setInput(input)); 
     }, 
     setUser: (user) => { 
      dispatch(setUser(user)); 
     }, 
     setFormModalStatus: (boolean) => { 
      dispatch(setFormModalStatus(boolean)); 
     }, 
     setSuccessModalStatus: (boolean) => { 
      dispatch(setSuccessModalStatus(boolean)); 
     } 
    }; 
}; 

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

Réducteur:

const dataReducer = (state = { 
    input: "", 
    users: [], 
    formModalStatus: false, 
    successModalStatus: false 
}, action) => { 
    switch (action.type) { 
     case "SET_INPUT": 
      state = { 
       ...state, 
       input: action.payload 
      }; 
      break; 
     case "SET_USER": 
      state = { 
       ...state, 
       users: [...state.users, action.payload] 
      }; 
      break; 
     case "SET_FORM_MODAL_STATUS": 
      state = { 
       ...state, 
       formModalStatus: action.payload 
      } 
     case "SET_SUCCESS_MODAL_STATUS": 
      state = { 
       ...state, 
       successModalStatus: action.payload 
      } 
    } 
    return state; 
}; 

export default dataReducer; 

l'action Appropriane:

export function setUser(user) { 
    return { 
     type: "SET_USER", 
     payload: user 
    }; 
} 

Répondre

1

Si vous pouviez fournir un échantillon de travail sur WebpackBin ou quelque chose , ça ld aide à mieux déboguer le problème. D'après mon expérience, cela se produit normalement lorsque l'état est muté. Pourriez-vous essayer d'utiliser le format suivant sur votre réducteur:

state = { 
      state.set('users', [...state.users, action.payload]) 
     }; 

La fonctionnalité existante mute l'état actuel à state=...

state = { 
      ...state, 
      users: [...state.users, action.payload] 
     }; 

PS: De plus, vous manquez break déclarations dans vos deux dernières actions cas dans votre réducteur. Et votre default case

+0

Merci pour votre réponse. Lorsque j'essaie votre variante - erreur dans la console @ state.set n'est pas une fonction. J'ai déjà essayé de nombreuses variantes de réducteurs de rendements immuables, pour l'instant c'est comme Jenna Rajani l'a écrit ici. Essayez de fournir un exemple de travail sur Webpackbin, mais cela prend du temps. PS: J'ai essayé d'utiliser uniquement l'état Réaction, mais j'ai fait face à ce problème avec React setState(), puis réécrire tout dans React + Redux et sortir dissapeared. Ensuite, je n'aime pas les modaux bootstrap et utilise React Modals et fait face au problème initial. –

0

Vous ne devez jamais muter l'état directement dans React ou Redux. Avec Redux, vous voulez toujours retourner un nouvel objet pour remplacer l'état précédent.

Peut-être essayer quelque chose comme ceci à la place?

switch (action.type) { 
    case 'SET_INPUT': 
     return { 
      ...state, 
      input: action.payload 
     }; 
    case 'SET_USER': 
     return { 
      ...state, 
      users: [...state.users, action.payload] 
     }; 
    case 'SET_FORM_MODAL_STATUS': 
     return { 
      ...state, 
      formModalStatus: action.payload 
     }; 
    case 'SET_SUCCESS_MODAL_STATUS': 
     return { 
      ...state, 
      successModalStatus: action.payload 
     }; 
    default: 
     return state; 
}