在事件触发时没有调用回调函数

问题描述:

我在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; 

这是我怎么会建立一个流量店 - 的关键点是:

  • 注册调度回调构造函数

  • 它使单个CHANGE_EVENT不变并更容易隐藏在店内。

  • 通常你会希望你的商店只有一个实例。所以当你输出它时你会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() 
    }); 
    } 
}