使用 Redux

2018-08-19  本文已影响0人  hankchang

简单使用

import { createStore } from "redux";

// 1. 新建 store
// 通过reducer建立
// 根据老的 state 和 action 生成新的 state
function counter(state = 0, action) {
  switch (action.type) {
    case "加机关枪":
      return state + 1;
    case "减机关枪":
      return state - 1;
    default:
      return 10;
  }
}

// 新建 store
const store = createStore(counter);

const init = store.getState();
console.log(init);

store.dispatch({ type: "加机关枪" });
console.log(store.getState());
store.dispatch({ type: "加机关枪" });
console.log(store.getState());
store.dispatch({ type: "减机关枪" });
console.log(store.getState());

优化

App.js

import React from "react";

class App extends React.Component {
  // constructor(props) {
  //   super(props)
  // }
  render() {
    const store = this.props.store;
    const num = store.getState();
    const addGun = this.props.addGun;
    const removeGun = this.props.removeGun;
    return (
      <div>
        <h1>
          现在有机枪
          {num}把
        </h1>
        <button onClick={() => store.dispatch(addGun())}>申请武器</button>
        <button onClick={() => store.dispatch(removeGun())}>上交武器</button>
      </div>
    );
  }
}

export default App;

index.js

import React from "react";
import ReactDom from "react-dom";
import { createStore } from "redux";
import App from "./App";
import { counter, addGun, removeGun } from "./index.redux";

const store = createStore(counter);

function render() {
  ReactDom.render(
    <App store={store} addGun={addGun} removeGun={removeGun} />,
    document.getElementById("root")
  );
}
render();

store.subscribe(render);

index.redux.js

const ADD_GUN = "加机关枪";
const REMOVE_GUN = "减机关枪";

// reducer
export function counter(state = 0, action) {
  switch (action.type) {
    case ADD_GUN:
      return state + 1;
    case REMOVE_GUN:
      return state - 1;
    default:
      return 10;
  }
}

// action creator
export function addGun() {
  return { type: ADD_GUN };
}

export function removeGun() {
  return { type: REMOVE_GUN };
}

更进一步, 让 Redux 可以处理异步

Redux 默认只处理同步, 异步任务需要 react-thunk 中间件

App.js

  render() {
    const store = this.props.store
    const num = store.getState()
    const addGun = this.props.addGun
    const removeGun = this.props.removeGun
    const addGunAsync = this.props.addGunAsync
    return (
      <div>
        <h1>现在有机枪{num}把</h1>
        <button onClick={() => store.dispatch(addGun())}>申请武器</button>
        <button onClick={() => store.dispatch(removeGun())}>上交武器</button>
        <button onClick={() => store.dispatch(addGunAsync())}>拖两天再给</button>
      </div>
    )
  }

index.js

import React from "react";
import ReactDom from "react-dom";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import App from "./App";
import { counter, addGun, removeGun, addGunAsync } from "./index.redux";

const store = createStore(counter, applyMiddleware(thunk));

function render() {
  ReactDom.render(
    <App
      store={store}
      addGun={addGun}
      removeGun={removeGun}
      addGunAsync={addGunAsync}
    />,
    document.getElementById("root")
  );
}

index.redux.js

export function addGunAsync() {
  return dispatch => {
    setTimeout(() => {
      dispatch(() => {
        dispatch(addGun());
      });
    }, 2000);
  };
}

调试工具

// index.js
import React from "react";
import ReactDom from "react-dom";
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import App from "./App";
import { counter, addGun, removeGun, addGunAsync } from "./index.redux";

const store = createStore(
  counter,
  compose(
    applyMiddleware(thunk),
    window.devToolsExtension ? window.devToolsExtension() : () => {}
  )
);

使用 React-redux

React-redux 具体使用

// index.js
import React from "react";
import ReactDom from "react-dom";
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import { Provider } from "react-redux";
import App from "./App";
import { counter } from "./index.redux";

const store = createStore(
  counter,
  compose(
    applyMiddleware(thunk),
    window.devToolsExtension ? window.devToolsExtension() : () => {}
  )
);

ReactDom.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);
// App.js
import React from "react";
import { connect } from "react-redux";
import { addGun, removeGun, addGunAsync } from "./index.redux";

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>
          现在有机枪
          {this.props.num}把
        </h1>
        <button onClick={this.props.addGun}>申请武器</button>
        <button onClick={this.props.removeGun}>上交武器</button>
        <button onClick={this.props.addGunAsync}>拖两天再给</button>
      </div>
    );
  }
}
const mapStatetoProps = state => {
  return { num: state };
};
const actionCreators = { addGun, removeGun, addGunAsync };

App = connect(
  mapStatetoProps,
  actionCreators
)(App);
export default App;

使用装饰器优化 Connect 代码

"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": ["babel-plugin-transform-decorators-legacy"]
  }
// App.js
import React from "react";
import { connect } from "react-redux";
import { addGun, removeGun, addGunAsync } from "./index.redux";

@connect(
  state => ({ num: state }),
  { addGun, removeGun, addGunAsync }
)
class App extends React.Component {
  render() {
    const num = this.props.num;
    const addGun = this.props.addGun;
    const removeGun = this.props.removeGun;
    const addGunAsync = this.props.addGunAsync;
    return (
      <div>
        <h1>
          现在有机枪
          {num}把
        </h1>
        <button onClick={addGun}>申请武器</button>
        <button onClick={removeGun}>上交武器</button>
        <button onClick={addGunAsync}>拖两天再给</button>
      </div>
    );
  }
}

export default App;

验证属性

import PropTypes from 'prop-types';

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

Greeting.propTypes = {
  name: PropTypes.string
};
上一篇 下一篇

猜你喜欢

热点阅读