I am kinda new to React and Reflux and modern JavaScript development. Trying to learn. So, I am making a component that is basically a sort of a chat window. A list with lines and an input box. When you type something into the input box and hit enter it adds the line to the list. I made it work with pure React using setState() and now I want to make it use a Reflux store. My component code goes like this
import React from 'react';
import Reflux from 'reflux';
import ConsoleActions from '../actions';
import ConsoleStore from '../stores';
export default React.createClass({
mixins: [Reflux.connect(ConsoleStore, "lines")],
render() {
var lines = this.state.lines.map(function(line) {
return(<li>{line}</li>)
});
return (
<ul>{lines}</ul>
<input onKeyUp={this.enter}/>
)
},
enter(e) {
if (e.keyCode == 13) {
ConsoleActions.addConsoleLines([e.target.value]);
e.target.value = null
}
}
});
my actions are
import Reflux from 'reflux';
export default Reflux.createActions(["addConsoleLines","clearConsoleLog",]);
and my store is import Reflux from 'reflux';
import Actions from './actions';
export default Reflux.createStore({
lines: [],
listenables: Actions,
getInitialState: function() {
return [];
},
addConsoleLines(lines) {
lines.forEach(line => {
this.lines.append(line);
});
},
clearConsoleLog() {
this.lines = []
}
});
Not sure what I am missing, Reflux.connect() should connect my store to state, but I get "TypeError: this.state.lines is undefined" error.
You should trigger change event when lines appended.
export default Reflux.createStore({
listenables: [Actions],
lines:[],
addConsoleLines(lines) {
let self=this;
lines.forEach(line => {
self.lines.append(line);
});
self.trigger('change',self.lines);
},
clearConsoleLog() {
this.lines = []
}
});
And in your component listen for that change event
export default React.createClass({
mixins: [Reflux.connect(ConsoleStore, "onChange")],
onChange(event,_lines){
this.setState({lines:_lines});
}
render() {
var lines = this.state.lines.map(function(line) {
return(<li>{line}</li>)
});
return (
<ul>{lines}</ul>
<input onKeyUp={this.enter}/>
)
},
enter(e) {
if (e.keyCode == 13) {
Actions.addConsoleLines([e.target.value]);
e.target.value = null
}
}
});
Edit1: Yes you are correct. There is another simple way to this.
The Reflux.connect()
mixin will check the store for a getInitialState
method. If found it will set the components getInitialState
. I think you forgot to return the initial state.
export default Reflux.createStore({
listenables: Actions,
getInitialState() {
return [];
},
addConsoleLines(lines) {
...
}