2017-10-06 3 views
0

Ich lerne Flux in ReactJS. Ich habe einen einfachen Code in ReactJS mit Flux-Muster geschrieben. In diesem Code werden einige Datensätze angezeigt und es gibt eine Option zum Hinzufügen eines neuen Datensatzes. Das Problem ist, dass, wenn ich ein Ereignis feuere, d. H. Wenn ich auf die Hinzufügen-Schaltfläche klicke, die Callback-Funktion nicht von this.on(CHANGE_EVENT, callback); aufgerufen wird und infolgedessen der neue Datensatz nicht auf dem Bildschirm angezeigt wird. Daher bitte sagen, warum diese callback Funktion nicht aufgerufen wird? Und wie behebt man dieses Problem?Rückruffunktion wird nicht bei Ereignis Feuer aufgerufen

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; 

Antwort

0

Dies ist, wie ich einen Fluss Speicher einrichten würde - die wichtigsten Punkte sind:

  • registrieren Sie den Dispatch Callback in Der Konstruktor

  • Es macht es einfacher, eine einzige CHANGE_EVENT Konstante zu haben und es im Laden zu verstecken.

  • Normalerweise möchten Sie, dass Ihre Filialen nur eine Instanz haben. Also, wenn Sie es exportieren, würden Sie export default new Store(). Auf diese Weise können alle Komponenten denselben Speicher verwenden.

Shop

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

-

Aus Sicht, sollten Sie Ihre Zuhörer in componentDidMount und denken Sie daran binden die Zuhörer in componentWillUnmount zu entfernen.

Ansicht

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() 
    }); 
    } 
} 
Verwandte Themen