Skip to content

dennybiasiolli/react-vuex

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
src
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

react-vuex

React bindings for Vuex inspired by react-redux project.

example workflow example workflow Codecov Status Coveralls Status

Donate with Liberapay

Installation

react-vuex requires React 16.0+, Vue 2.0+ and Vuex 3.0+

npm install --save react-vuex

This assumes that you’re using npm package manager with a module bundler like Webpack or Browserify to consume CommonJS modules.

Documentation

To look at some example projects, take a look at the examples section of this repo.

Example use

  • configure your store with state, getters, mutations and actions, according to Vuex documentation

    /*
     * actions.js
     */
    
    export const INCREMENT_ASYNC = 'INCREMENT_ASYNC';
    
    export default {
      incrementAsync: (value = 1) => ({
        type: INCREMENT_ASYNC,
        value,
      }),
    };
    
    
    /*
     * mutations.js
     */
    
    export const INCREMENT = 'INCREMENT';
    export const INCREMENT_START = 'INCREMENT_START';
    export const INCREMENT_STOP = 'INCREMENT_STOP';
    
    export default {
      increment: (value = 1) => ({
        type: INCREMENT,
        value,
      }),
    };
    
    
    /*
     * store.js
     */
    
    import Vue from 'vue';
    import Vuex from 'vuex';
    import { INCREMENT, INCREMENT_START, INCREMENT_STOP } from './mutations';
    import { INCREMENT_ASYNC } from './actions';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state: {
        count: 0,
        isIncrementing: false,
      },
      getters: {
        countGreaterThan2: (state, getters) => state.count > 2,
      },
      mutations: {
        [INCREMENT](state) {
          state.count += 1;
        },
        [INCREMENT_START](state) {
          state.isIncrementing = true;
        },
        [INCREMENT_STOP](state) {
          state.isIncrementing = false;
        },
      },
      actions: {
        [INCREMENT_ASYNC]({ commit, state }, payload) {
          commit(INCREMENT_START);
          return new Promise((resolve) => {
            setTimeout(() => {
              commit(INCREMENT);
              resolve();
            }, 500);
          }).then(() => commit(INCREMENT_STOP))
            .then(() => state.count);
        },
      },
    });
  • use Provider in your app

    This will pass the store to all subcomponents of the app

    /*
     * index.js
     */
    
    import React from 'react';
    import { render } from 'react-dom';
    import { Provider } from 'react-vuex';
    import App from './components/App';
    import store from './store';
    
    render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('root'),
    );
  • create your container component mapping state, dispatch, commit and getter to the store

    /*
     * containers/MyContainer.js
     */
    
    import { connect } from 'react-vuex';
    import MyComponent from '../components/MyComponent';
    import mutations from '../mutations';
    import actions from '../actions';
    
    const mapStateToProps = (state, ownProps) => ({
      myCount: state.count,
    });
    const mapDispatchToProps = (dispatch, ownProps) => ({
      onIncrementAsync: val => dispatch(actions.incrementAsync(val)),
    });
    const mapCommitToProps = (commit, ownProps) => ({
      onIncrement: () => commit(mutations.increment()),
    });
    const mapGetterToProps = (getter, ownProps) => ({
      isGreaterThan2: getter.countGreaterThan2,
    });
    
    const MyContainer = connect(
      mapStateToProps,
      mapDispatchToProps,
      mapCommitToProps,
      mapGetterToProps,
    )(MyComponent);
    
    export default MyContainer;
  • create your presentational component using mapped props

    /*
     * components/MyComponent.js
     */
    
    import React from 'react';
    import PropTypes from 'prop-types';
    
    export default class MyComponent extends React.PureComponent {
      constructor(props, context) {
        super(props, context);
        this.handleInc = this.handleInc.bind(this);
        this.handleIncAsync = this.handleIncAsync.bind(this);
      }
      handleInc() {
        if (this.props.onIncrement) {
          this.props.onIncrement();
        }
      }
      handleIncAsync() {
        if (this.props.onIncrementAsync) {
          this.props.onIncrementAsync().then(() => {}));
        }
      }
      render() {
        return (
          <div>
            Count is {this.props.myCount !== undefined && `${this.props.myCount}, `}
            greater than 2: {this.props.isGreaterThan2 ? 'yes' : 'no'}
            {this.props.onIncrement &&
              <button onClick={this.handleInc}>Increment Sync</button>
            }
            {this.props.onIncrementAsync &&
              <button onClick={this.handleIncAsync}>Increment Async</button>
            }
          </div>
        );
      }
    }
    
    MyComponent.defaultProps = {
      children: undefined,
      isGreaterThan2: false,
      myCount: 0,
      onIncrement: undefined,
      onIncrementAsync: undefined,
    };
    
    MyComponent.propTypes = {
      children: PropTypes.node,
      isGreaterThan2: PropTypes.bool,
      myCount: PropTypes.number,
      onIncrement: PropTypes.func,
      onIncrementAsync: PropTypes.func,
    };
  • use your container component in app

    import React from 'react';
    import MyContainer from '../containers/MyContainer';
    
    export default class App extends React.Component {
      constructor(props, context) {
        super(props, context);
        this.state = {
          testValue: 123,
        };
      }
    
      render() {
        return (
          <div>
            <MyContainer />
          </div>
        );
      }
    }

License

MIT

Support on Beerpay or Liberapay

Hey dude! Help me out for a couple of 🍻!

Beerpay Beerpay

Donate with Liberapay