reflux / refluxjs

A simple library for uni-directional dataflow application architecture with React extensions inspired by Flux
BSD 3-Clause "New" or "Revised" License
5.36k stars 330 forks source link

store tigger not work #496

Closed Heymancn closed 7 years ago

Heymancn commented 7 years ago

My project is react ES6 style. I find my store tigger does not work . Componet just render once.My code is like https://github.com/reflux/refluxjs#react-es6-component-example

export default Reflux.createStore({

        listenables: [homeActions],

        init(){
                this.state = {};
        },

        onInit(){
                let url = "/api/admin/home/getCounts"
                let payload = {payload: {}}
                let func = ((result) => {
                        this.state.list = result;
                        this.trigger(this.state)
                })
                fetchData(url, payload, func)
        },
})

class Home extends Reflux.Component{
        constructor(props) {
                super(props);
                this.homeStore = homeStore;
                homeActions.init();
        }

        render(){
                console.log(this.homeStore.state);
                if(isEmpty(this.homeStore.state)) return null;
                return (
                        <div>

                        </div>
                )
        }

}

export default Home
BryanGrezeszak commented 7 years ago

You're sorta only half ES6 style. You should look at the Reflux.Store part of the docs for creating your stores.

The docs right now are a mixture because they were trying to explain each part of the new ES6 API while relating it to the older parts. But you really should use all ES6 style. In fact the docs are being refactored right now to only show the ES6 API.

That said, one issue that jumps out at me right from the start is this:

this.homeStore = homeStore;

There is no this.homeStore in the API. You set this.store to your store. So: this.store = homeStore.

And then the state from homeStore would simply get mixed into your state. So you wouldn't do things like if(isEmpty(homeStore.state)) return null;, that store's state is part of your component now. So if there's a this.state.list value in the store, then there'll be a this.state.list value in the component.

Or better yet, do it all as ES6 (i.e. do the store ES6 style as well):

class HomeStore extends Reflux.Store
{
    constructor()
    {
        super();
        this.listenables = homeActions;
        this.state = {list: null};
    }

    onInit()
    {
        let url = "/api/admin/home/getCounts"
        let payload = {payload: {}}
        let func = ((result) => {
            this.setState({list:result});
        })
        fetchData(url, payload, func)
    }
}

class Home extends Reflux.Component
{
    constructor(props)
    {
        super(props);
        this.store = HomeStore;
        homeActions.init();
    }

    render()
    {
        if(this.state.list === null)
            return null;

        return (
            <div>{this.state.list}</div>
        )
    }
}

Notice that you assign the class itself to this.store. A singleton instance of the class will be created internally. And notice that you don't have to use trigger in the store. Just use setState in it like you would to set state in a react component.

I've tested the above and it works, so closing this issue.