retalk
The Simplest Redux
Last updated 15 days ago by nanxiaobei .
MIT · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install retalk 
SYNC missed versions from official npm registry.
Retalk

Retalk is a best practice for Redux. just simple, smooth, and smart.

Travis Codecov npm version npm downloads license

English | 简体中文


Features

  • Simplest Redux: Just state and actions, clear than ever before.
  • Two API totally: createStore and withStore, no more annoying concepts.
  • Async import model: Fully code splitting support for models.
  • Auto loading state: Send request, and loading state is ready to use.

Install

yarn add retalk

or

npm install retalk

Usage

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider, connect } from 'react-redux';
import { createStore, withStore } from 'retalk';

// 1. Model
const counter = {
  state: {
    count: 0,
  },
  actions: {
    increment() {
      const { count } = this.state;
      this.setState({ count: count + 1 });
    },
    async incrementAsync() {
      await new Promise((resolve) => setTimeout(resolve, 1000));
      this.increment();
    },
  },
};

// 2. View
const Counter = connect(...withStore('counter'))(
  ({ count, increment, incrementAsync, loading }) => (
    <div>
      {count}
      <button onClick={increment}>+</button>
      <button onClick={incrementAsync}>+ Async{loading.incrementAsync && '...'}</button>
    </div>
  ),
);

// 3. Store
const store = createStore({ counter });

const App = () => (
  <Provider store={store}>
    <Counter />
  </Provider>
);

ReactDOM.render(<App />, document.getElementById('root'));

Demo

Edit retalk

API

createStore()

createStore(models[, options])

const store = createStore({ modelA, modelB }, { useDevTools: false, plugins: [logger] });

options.useDevTools

type: boolean, default: true. Enable Redux DevTools, make sure the extension's version >= v2.15.3 and not v2.16.0.

options.plugins

type: array, default: []. Add one middleware as an item to this array, passed to applyMiddleware.

withStore()

withStore(...modelNames)

const DemoConnected = connect(...withStore('modelA', 'modelB'))(Demo);

Use withStore to eject all state and actions of a model to a component's props, you can eject more than one model.

withStore must be passed in rest parameters syntax to connect().

action

actions: {
  someAction() {
    // What's in an action's `this` context?

    // this.state -> Get state
    // this.setState() -> Set state
    // this.someOtherAction() -> Call actions

    // this.someModel.state -> Get another model's state
    // this.someModel.someAction() -> Call another model's actions
  },
  async someAsyncAction() {
    // Automatically `loading.someAsyncAction` can be use
  }
}

FAQ

Async import model?

Use createStore to initalize the store, then use libraries like loadable-components to dynamic import both the component and model.

Then use store.addModel(name, model) to eject the async imported model to store.

Here is a loadable-components example:

import React from 'react';
import loadable from 'loadable-components';

const AsyncCounter = loadable(async (store) => {
  const [{ default: Counter }, { default: model }] = await Promise.all([
    import('./counter/index.jsx'),
    import('./counter/model'),
  ]);
  store.addModel('counter', model); // Key to import async model
  return (props) => <Counter {...props} />;
});

Customize state and actions?

Use mapStateToProps and mapDispatchToProps when need some customization, without using withStore.

const mapState = ({ counter: { count } }) => ({
  count,
});

const mapActions = ({ counter: { increment, incrementAsync } }) => ({
  increment,
  incrementAsync,
});
// First parameter to `mapDispatchToProps` is `dispatch`.
// `dispatch` is a function, but in `mapActions` above, we treat it like an object.
// Retalk did some tricks here, it's the `dispatch` function, but bound models on it.

export default connect(
  mapState,
  mapActions,
)(Counter);

Support HMR?

For example change index.js to:

if (module.hot) {
  module.hot.accept('./App', () => {
    render();
  });
}

Then Provider must inside the App component:

const App = () => (
  <Provider store={store}>
    <Counter />
  </Provider>
);

If want to keep the store, change store.js to:

if (!window.store) {
  window.store = createStore({ ... });
}

export default window.store;

Proxy error?

Retalk uses Proxy, if old browsers not support, please try proxy-polyfill.

License

MIT License (c) nanxiaobei

Current Tags

  • 2.3.0                                ...           latest (15 days ago)

20 Versions

  • 2.3.0                                ...           15 days ago
  • 2.2.4                                ...           a month ago
  • 2.2.2                                ...           4 months ago
  • 2.2.1                                ...           4 months ago
  • 2.2.0                                ...           4 months ago
  • 2.1.0                                ...           7 months ago
  • 2.0.0                                ...           7 months ago
  • 1.2.3                                ...           8 months ago
  • 1.2.2                                ...           8 months ago
  • 1.2.1                                ...           8 months ago
  • 1.2.0                                ...           8 months ago
  • 1.1.0                                ...           a year ago
  • 1.0.8                                ...           a year ago
  • 1.0.7                                ...           a year ago
  • 1.0.6                                ...           a year ago
  • 1.0.5                                ...           a year ago
  • 1.0.4                                ...           a year ago
  • 1.0.3                                ...           a year ago
  • 1.0.2                                ...           a year ago
  • 1.0.0                                ...           a year ago
Maintainers (1)
Downloads
Today 0
This Week 0
This Month 27
Last Day 0
Last Week 2
Last Month 45
Dependencies (2)
Dev Dependencies (11)
Dependents (0)
None

Copyright 2014 - 2017 © taobao.org |