2016-08-11 4 views
0

Ich habe diesen CodeWann und wo löschen Sie den Status in ReactJs?

import React from 'react'; 

import 'materialize-css/sass/materialize.scss'; 
import 'materialize-css/js/materialize.js'; 
import 'font-awesome/scss/font-awesome.scss'; 
import '../styles/main.scss'; 

export default class AddStorageModal extends React.Component { 
    constructor() { 
     super(); 
     this.state = { storageName: "", sharingKey: "" }; 
    } 
    handleChange(event) { 
     this.setState({ [event.target.name]: event.target.value }); 
    } 
    validate() { 
     if (this.state.storageName === "" && this.state.sharingKey == "") { 
      console.log("validation error"); 
      return false; 
     } 
     this.props.createNewStorage(this.state); 
    } 
    resetForm() { 
     this.setState({ storageName: "", sharingKey: "" }) 
     $(function() { 
      Materialize.updateTextFields(); 
     }); 
    } 
    render() { 
     if (this.props.storages.openAddStorageModal) { 
      $('#add-new-storage-modal').openModal({ dismissible: false }); 
     } 
     else { 
      $('#add-new-storage-modal').closeModal(); 
      this.resetForm(); 
     } 
     return (
      <div id="add-new-storage-modal" className="modal" > 
       <div className="modal-content"> 
        <h6>Enter your new Storage (Freezer, Pantry, etc.) </h6> 
        <div className="row"> 
         <form> 
          <div className="input-field col s12 m12 l12 "> 
           <input id="storage_name" type="text" value={this.state.storageName} name="storageName" onChange={ (event) => this.handleChange(event) } /> 
           <label htmlFor="storage_name">Storage Name</label> 
          </div> 
          <br /> 
          <h4 className="center">OR</h4> 
          <h6>Enter in the sharing key you were given.</h6> 
          <div className="input-field col s12 m12 l12 "> 
           <input id="sharing_key" type="text" value={this.state.sharingKey} name="sharingKey" onChange={ (event) => this.handleChange(event) } /> 
           <label htmlFor="sharing_key">Sharking Key</label> 
          </div> 
         </form> 
        </div> 
       </div> 
       <div className="modal-footer"> 
        <a href="#!" className="waves-effect waves-green btn-flat left" onClick={() => this.validate() }>Add</a> 
        <a href="#!" className="waves-effect waves-green btn-flat" onClick={() => this.props.loadAddStorageModal(false) }>Cancel</a> 
       </div> 
      </div> 
     ) 
    } 
} 

Mein Orignal Plan jedes Mal meine modalen Dialogwieder rendert war ich die Form Werte zurückgesetzt durch meine resetform() -Methode aufrufen.

Dies funktioniert nicht, da ich Fehler in Bezug auf "Zustand ändern" im Rendern bekomme, was jetzt für mich Sinn macht, da es die Komponente zum Rendern bringt.

Aber das führt zu mir zu den Fragen wo lösche ich dann den Zustand? Ich versuche dem Redux-Muster zu folgen.

Ich konnte das Löschen in "Validate()" -Methode tun, wenn auf das Hinzufügen geklickt wird.

Jedoch "createNewStorage" führt einen Ajax-Aufruf aus. Ich bin mir nicht sicher, wie ich mit der Situation umgehen würde, wenn der Ajax-Aufruf fehlschlägt. Als Benutzer würde ich erwarten, dass eine Fehlermeldung angezeigt wird, aber das Modal sollte immer noch mit meinen eingegebenen Werten geöffnet sein.

Hier ist der vollständige Code, falls erforderlich.

import React from 'react'; 
import {connect} from 'react-redux'; 
import {bindActionCreators} from 'redux'; 
import 'materialize-css/sass/materialize.scss'; 
import NavigationContainer from './NavigationContainer'; 
import StorageItemsContainer from './StorageItemsContainer' 

import AddStorageModal from './AddStorageModal.js' 
import {loadAddStorageModal, createNewStorage} from '../actions/StorageActions.js' 
import '../styles/main.scss'; 


class App extends React.Component { 
    render() { 
    return (
     <div> 
     <NavigationContainer /> 
     <div className="container"> 
      <StorageItemsContainer /> 
     </div> 
     <AddStorageModal {...this.props} /> 
     </div> 
    ) 
    } 
} 

function mapStateToProps(state) { 
    return { 
     storages: state.storages 
    }; 
} 

function matchDispatchToProps(dispatch){ 
    return bindActionCreators({loadAddStorageModal: loadAddStorageModal, createNewStorage: createNewStorage}, dispatch); 
} 


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

Aktion

export function fetchStorage() { 
    return function(dispatch) { 
     var payload = [ 
     { 
      id: 1, 
      name: "Fridge2", 
      selected: true 
     }, 
     { 
      id: 2, 
      name: "Closet2", 
      selected: false 
     }, 
     { 
      id: 3, 
      name: "Car2", 
      selected: false 
     } 
    ]; 
    dispatch({type: "Fetch_Storage", payload: payload}); 
    } 
} 

export function loadAddStorageModal(load) { 
    return function(dispatch) { 
     dispatch({type: "Load_Add_Storage_Modal", payload: load}); 
    } 
} 

export function createNewStorage(storage) { 
    return function(dispatch) { 
     dispatch({type: "New_Storage_Created", payload: storage}); 
    } 
} 

export function selectStorage(storageId) 
{ 
    return function(dispatch) { 
     dispatch({type: "Select_Storage", payload: storageId}); 
    } 
} 

Reducer

export default function reducer(state = { 
    fetchedStorages: [], 
    openAddStorageModal: false, 
    selectedStorage: null 
}, action) { 
    switch (action.type) { 
     case "Fetch_Storage": { 
      var selected; 
      if(state.fetchedStorages != []) 
      { 
       selected = action.payload[0] 
      } 
      return { 
       fetchedStorages: action.payload, 
       selectedStorage: selected 
      } 
     } 
     case "Load_Add_Storage_Modal": { 
      return { 
       openAddStorageModal: action.payload, 
       fetchedStorages: state.fetchedStorages, 
       selectedStorage: state.selectedStorage 
      } 
     } 
     case "New_Storage_Created": { 
      var lastStorage = state.fetchedStorages.slice(-1); // just for now 
      return { 
       openAddStorageModal: false, 
       fetchedStorages: state.fetchedStorages.concat({ id: lastStorage[0].id + 1, name: action.payload.storageName}), 
       selectedStorage: state.selectedStorage 
      } 
     } 
     case "Select_Storage": { 
      var existingStorages = state.fetchedStorages; 
      var selectedStorage = null; 
      for (var i = 0; i < existingStorages.length; i++) { 
       var storage = existingStorages[i]; 
       if (action.payload == storage.id) { 
        storage.selected = true; 
        selectedStorage = storage; 
       }else{ 
        storage.selected = false; 
       } 
       existingStorages[i] = storage; 
      } 
      return { 
       fetchedStorages: existingStorages, 
       selectedStorage: selectedStorage 
      } 

     } 
    } 


    return state; 
} 

Antwort

0

Ja, können Sie nur setState in Lifecycle-Methoden aufrufen und in onEvents.

In Ihrem Fall, weil Sie auf die Stützen setzen this.props.storages.openAddStorageModal

Sie Ihren Zustand im Inneren componentWillReceivePropsLifecycle-Methode einstellen könnte.

es wird mit den nextProps Werte aufgerufen werden, beachten Sie, dass Requisiten sind zu diesem Zeitpunkt nicht festgelegt, und Sie können das nextProps Argument mit Ihrem bisherigen Requisiten in this.props

fügen Sie diese zu Ihrer Komponente vergleichen, und es sollte funktionieren fein:

componentWillReceiveProps(nextProps) { 
    if (nextProps.storages.openAddStorageModal) { 
     $('#add-new-storage-modal').openModal({ dismissible: false }); 
    } else { 
     $('#add-new-storage-modal').closeModal(); 
     this.resetForm(); // will work fine here.. 
    } 
} 
0

Sie sollten eine Aktion haben, die den Status löscht - dispatch(props.clearForm).

Ihr Geschäft beim Empfang des Aktionsereignisses sollte dafür verantwortlich sein, seinen Geschäftszustand zu löschen, und somit wird ein erneuter Rendervorgang ausgelöst.

case CLEAR_FORM: 
    // return new empty state object 

Das Formular sollte Werte basieren Anzeige über den Zustand des Ladens und so, wenn die Wieder machen geschieht die Felder leer sein sollte.

Wenn Sie bei jedem Tastendruck neue Werte in den Speicher schreiben, können Sie das Aktionsereignis entprellen lassen, da sonst Probleme mit der Leistung auftreten können.

+0

Ich verwende Redux, also habe ich nur 1 Geschäft. Ich dachte nicht, dass es richtig wäre, wenn meine 2 Staaten außerhalb dieser Komponente leben würden, da sie nur dort benutzt werden.Sobald der Benutzer auf "Hinzufügen" geklickt hat, wird es zu meinem Store hinzugefügt, aber bis dahin dachte ich, es wäre besser, lokal zu sein, da nichts anderes versuchen sollte, Werte zu verwenden, die noch nicht finalisiert sind. – chobo2

Verwandte Themen