2016-08-11 8 views
0

は、私はこのコードを&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> 
     ) 
    } 
} 

を持っている私のorignal計画は私のモーダルダイアログの再描画し、私は私のresetForm()メソッドを呼び出すことにより、フォームの値をリセットするたびでした。

レンダリングで「状態の変更」に関するエラーが発生するため、これは機能しません。これは、コンポーネントが再レンダリングされるため、現在わたしにとって意味のあるものです。

しかし、これは質問に私をもたらします。それでは、私はその状態をどこから取り除きますか?私はreduxパターンに従おうとしています。

追加をクリックすると、「検証」()メソッドでクリアを行うことができます。

しかし、 "createNewStorage"はajax呼び出しを行います。私は、ajax呼び出しが失敗した場合、どのように状況を処理するのか不明です。ユーザーとして、私はエラーメッセージが表示されるが、モーダルは入力された値で開いているはずです。

必要に応じてフルコードです。

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); 

アクション

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}); 
    } 
} 

リデューサー

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; 
} 

答えて

0

はい、あなただけのライフサイクルメソッドでとonEventssetStateを呼び出すことができます。あなたのケースでは

、あなたが小道具this.props.storages.openAddStorageModal

に頼っているので、あなたがcomponentWillReceivePropsライフサイクル・メソッド内のあなたの状態を設定することができます。

それは小道具が、この時点で設定されていないことに注意してください、nextProps値で呼び出されます、そして、あなたのコンポーネントにこれを追加し、それが動作するはずthis.props

に以前の小道具でnextProps引数を比較することができます詳細:

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

状態をクリアするアクションが必要です。dispatch(props.clearForm)

アクションイベントを受け取った店舗は、店舗状態をクリアする責任があり、したがって再レンダリングがトリガーされます。

case CLEAR_FORM: 
    // return new empty state object 

フォームが店舗の状態に基づいて値を表示し、そうしなければならない再レンダリングのフィールドが空でなければなりません発生したとき。

すべてのキーストロークで店舗に新しい値を書き込んでいる場合は、アクションイベントをデバウンスする必要があります。それ以外の場合は、問題が発生する可能性があります。

+0

私はReduxを使用していますので、1店舗しかありません。私は、彼らがそこでしか使われていないので、そのコンポーネントの外に住んでいる私の2つの州にとって正しいとは思わなかった。ユーザーが「追加」をクリックすると、それが私の店に追加されますが、それまではまだ確定されていない値を使用しようとするべきではないので、ローカルになる方が良いと思っていました。 – chobo2

関連する問題