SoluableNonagon
SoluableNonagon

Reputation: 11755

React and Flux - how to tie view to store data

I started learning React with Flux and I am having some trouble.

I have a store and two views (components) and I would like to update one view when the store data changes, but I'm not sure how to tie the two together.

What happens is this:

I click a button in view 1, this modifies data in the store, then this should update view two.

view1 onClick => dispatch action => modify store data => update view2

I have everything except the last part, tying the view and the store when changes are made to the store. All this currently does is modify a class name, but I can see other functions for it later on.

So my question is, how can I tie the store to the state of the view?

view2 (Homepage)

var React = require('react');
var DefaultLayout = React.createFactory(require('../layouts/Default'));
var ReactGridLayout = React.createFactory(require('react-grid-layout'));

var desktopStore = require("../stores/DesktopStore");
// var classNames = require('classnames');

var HomePage = React.createClass({
  displayName: 'Index.jsx',

  getInitialState: function(){
    return {zoomed: desktopStore.get('zoom')};
  },

  getDefaultProps: function() {
    return {
      layout: DefaultLayout
    };
  },

  render: function() {
    var parentClassString = "desktop"; // base class

    if(this.state.zoomed){
      parentClassString += " zoomed"; // add a class based on the zoomed property
    }

    return (
        <div className={parentClassString}>

            <ReactGridLayout className="layout" cols={80} rowHeight={30} verticalCompact={false}
                initialWidth={10} autoSize={false} isResizable={false}>
                <div key={1} _grid={{x: 0, y: 0, w: 1, h: 1}} >1</div>
                <div key={2} _grid={{x: 0, y: 0, w: 1, h: 1}} >2</div>
                <div key={3} _grid={{x: 0, y: 0, w: 1, h: 1}} >3</div>
                <div key={4} _grid={{x: 0, y: 0, w: 1, h: 1}} >4</div>
                <div key={5} _grid={{x: 0, y: 0, w: 1, h: 1}} >5</div>
                <div key={6} _grid={{x: 0, y: 0, w: 1, h: 1}} >6</div>
            </ReactGridLayout>

        </div>
    );
  }
});

module.exports = HomePage;

View1 (Header)

var _name = 'TopHeader.jsx';
var React = require('react');
var DesktopApi = require('../utilities/DesktopApi');

var TopHeader = React.createClass({

  displayName: _name,

  handleClick: function(){
    DesktopApi.toggleZoom(); // this goes to the dispatcher and emits a change to update the desktopStore
  },

  render() {
    return (
        <div className="top-header">
            <span>Header</span>
            <span className="plus" onClick={this.handleClick}> [+] </span>
        </div>
    );
  }

});

module.exports = TopHeader;

Upvotes: 0

Views: 118

Answers (2)

ycdesu
ycdesu

Reputation: 735

If you want to create a mixin to bind the views to stores, you can read fluxxor's source. Here's the sample of storeWatchMixin. Or you can use higher order component to wrap your component.

Upvotes: 1

SoluableNonagon
SoluableNonagon

Reputation: 11755

The official facebook guide helped out here, I can create listeners with componentDidMount and remove them with componentWillUnmount

componentDidMount: function() {
  desktopStore.addChangeListener(this._onChange);
},

componentWillUnmount: function() {
  desktopStore.removeChangeListener(this._onChange);
},

_onChange: function(){ 
    this.setState({zoom: true});
}

Upvotes: 1

Related Questions