LoginSignup
7
5

More than 5 years have passed since last update.

この規模でreduxは草だけど流石にstoreとactionは別で管理したいって時はredux-zeroがオススメ

Last updated at Posted at 2018-06-16

:writing_hand: redux-zero

version
node:8.11.3
yarn:1.7.0
setup
npx create-react-app my-app --scripts-version=react-scripts-ts
cd my-app
yarn add redux-zero axios
yarn add -D json-server
touch db.json src/store.ts src/actions.ts
tslint.json
  "rules": {
    "no-console": false,
    "no-empty-interface": false,
    "no-shadowed-variable": false,
    "variable-name": false
  }
db.json
{
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ]
}
store.ts
import createStore from "redux-zero";

interface IState {
  count?: number;
  data?: any;
  loading?: boolean;
}

const initialState: IState = { count: 1, data: [], loading: false };

// tsエラーがでるので一旦any型へ格納
const _createStore: any = createStore;
const store = _createStore(initialState);

export default store;
actions.ts
import client from "axios";

const actions = ({ setState }: any) => ({
  decrement: (state: any) => ({ count: state.count - 1 }),
  // 非同期もいける
  getComments: (state: any) => {
    setState({ loading: true });
    return client
      .get("http://localhost:3000/comments")
      .then(payload => ({ data: payload.data, loading: false }))
      .catch(error => ({ error, loading: false }));
  },
  increment: (state: any) => ({ count: state.count + 1 })
});

export default actions;
App.tsx
import * as React from "react";
import { connect } from "redux-zero/react";
import actions from "./actions";

interface IProps {
  store?: any;
}

interface IState {}

const mapToProps = ({ count, data, loading }: any) => ({
  count,
  data,
  loading
});

class App extends React.Component<IProps, IState> {
  public constructor(readonly props: any) {
    super(props);
  }

  public render(): JSX.Element {
    return (
      <div>
        <h1>{this.props.count}</h1>
        <div>
          <button onClick={this.props.decrement}>decrement</button>
          <button onClick={this.props.increment}>increment</button>
          <button onClick={this.props.getComments}>getComments</button>
        </div>
        <ul>{this.props.data.map((v: any) => <li key={v.id}>{v.body}</li>)}</ul>
      </div>
    );
  }
}

export default connect(
  mapToProps,
  actions
)(App);
index.tsx
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Provider } from "redux-zero/react";
import App from "./App";
import store from "./store";

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

ReactDOM.render(<Root />, document.getElementById("root") as HTMLElement);
start
yarn run json-server --watch db.json
yarn start

:moyai: 「...このライブラリ略したらリゼロですやん」

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5