2017-10-06 28 views
0

私はReactJSでFluxを学習しています。私はFluxパターンを使ってReactJSで簡単なコードを書いています。このコードでは、いくつかのレコードが表示されており、新しいレコードを追加するオプションがあります。問題は、イベントを発生させると、つまり、追加ボタンをクリックすると、コールバック関数がthis.on(CHANGE_EVENT, callback);から呼び出されていないため、その結果、新しいレコードが画面に表示されないということです。したがって、なぜこのcallback関数が呼び出されていないのかを教えてください。そしてこの問題を解決するには?イベントの呼び出しでコールバック関数が呼び出されない

Store.js

import React from 'react'; 
import Dispatcher from './Dispatcher.js'; 
import { EventEmitter } from "events"; 

class Store extends EventEmitter { 

    constructor() { 
     super(); 
     this.records = [ 
      { 
       id: 1, 
       name: 'First Record' 
      }, 
      { 
       id: 2, 
       name: 'Second Record' 
      }, 
      { 
       id: 3, 
       name: 'Third Record' 
      }, 
      { 
       id: 4, 
       name: 'Fourth Record' 
      }, 
      { 
       id: 5, 
       name: 'Fifth Record' 
      } 
     ] 
    }; 

    createRecord(name, id) { 
     this.records.push({ 
      id: id, 
      name: name 
     }); 
     this.emit("change"); 
    } 

    addChangeListener(CHANGE_EVENT, callback) { 
     this.on(CHANGE_EVENT, callback); 
    } 

    handleActions(action) { 
     switch(action.type) { 
      case "ADD_RECORD": { 
       this.createRecord(action.name, action.id); 
       break; 
      } 
     } 
    } 

    getRecords() { 
     return this.records; 
    } 
}; 

const recordsStore = new Store(); 
Dispatcher.register(recordsStore.handleActions.bind(recordsStore)); 

export default Store; 

View.jsx

import React from 'react'; 
import Store from './Store.js'; 
import {addRecord} from "./Action.js"; 


class View extends React.Component { 
    constructor() { 
     super(); 
     this.Store = new Store(); 
     this.state = {records: this.Store.getRecords()}; 
    } 

    render() { 
     return (
      <div className="container" style={{marginTop:'25px'}}> 
       <ul className="list-group"> 
        <li style={{backgroundColor:'#696969', color:'#f5f5f5', textAlign:'center', padding:'5px', fontSize:'16px', borderRadius:'5px 5px 0px 0px'}}><b>Records</b></li> 
        {this.state.records.map((eachRecord,index) => 
         <ListItem key={index} singleRecord={eachRecord} /> 
        )} 
       </ul> 
       <input type="text" ref="input"/> 
       <button onClick={()=>addRecord(this.refs.input.value)}>Add</button> 
      </div> 
     ); 
    } 

    componentWillMount() { 
     this.Store.addChangeListener("change", this.updateStore); 
    } 

    updateStore() { 
     this.setState({ 
      records: this.Store.getRecords() 
     }); 
    } 
} 

class ListItem extends React.Component { 
    render() { 
     return (
      <li className="list-group-item" style={{cursor:'pointer'}}> 
       <b>{this.props.singleRecord.name}</b> 
       <button style={{float:'right'}}>Delete</button> 
      </li> 
     ); 
    } 
} 

export default View; 

答えて

0

これは、私は、フラックスストアを設定する方法をある - 重要なポイントは以下のとおりです。

  • ディスパッチコールバックをコンストラクタ

  • これにより、定数が1つしかなく、ストア内に隠れることが容易になります。

  • 通常、店舗には1つのインスタンスのみが必要です。したがって、エクスポートするとexport default new Store()となります。そうすれば、すべてのコンポーネントが同じストアを使用できるようになります。

ストア

const CHANGE_EVENT = 'change'; 

class Store extends EventEmitter { 
    constructor() { 
    super(); 
    Dispatcher.register(this.handleActions.bind(this)); 
    } 

    createRecord(name, id) { 
    // code.. 
    this.emitChange(); 
    } 

    emitChange() { 
    this.emit(CHANGE_EVENT); 
    } 

    addChangeListener(callback) { 
    this.on(CHANGE_EVENT, callback); 
    } 

    removeChangeListener(callback) { 
    this.removeListener(CHANGE_EVENT, callback); 
    } 

    handleActions(action) { 
    switch (action.type) { 
     case 'ADD_RECORD': { 
     this.createRecord(action.name, action.id); 
     break; 
     } 
    } 
    } 

    getRecords() { 
    return this.records; 
    } 
} 

export default new Store(); 

- ビューで

、あなたはcomponentDidMountであなたのリスナーをバインドし、componentWillUnmountでリスナーを削除するには覚えておいてください。

ビュー

import Store from './Store'; 

class View extends React.Component { 
    constructor() { 
    super(); 
    this.state = {records: Store.getRecords()}; 
    } 

    render() { 
    // code.. 
    } 

    componentDidMount() { 
    Store.addChangeListener(this.updateStore); 
    } 

    componentWillUnmount() { 
    Store.removeChangeListener(this.updateStore); 
    } 

    // use this syntax to keep context or use .bind in the constructor 
    updateStore =() => { 
    this.setState({ 
     records: Store.getRecords() 
    }); 
    } 
} 
関連する問題