Skip to content
Branch: master
Find file History

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
src
.gitignore
README.md
index.html
package.json
webpack.config.js

README.md

计数器 react-redux

Start

npm i

npm start

React-Redux

Redux 是一款状态管理库,并且提供了 react-redux 库来与 React 亲密配合,这两者的关系如下图:

react-redux流程图

继续实现计数器,完整 Demo 可以看这里

src 目录下大体结构:

├── actions
│   └── counter.jsx
├── components
│   └── app.jsx
├── reducers
│   └── counter.jsx
└── store
    └── app.jsx
├── index.jsx

首先,看入口文件 index.js:

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";

import reducer from "./reducers/counter.jsx";
import App from "./store/app.jsx";

const store = createStore(reducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

Provider 组件,其实就是 Context 实现的,提供一个状态供跨组件使用,只需要把 store 给他传过去,所有的子组件就可以通过 props 属性拿到状态值。

let Context = React.createContext();
class Provider extends Component {
  // 将React-redux中的Provide包装了react提供的API生成的Context.Provider
  //<Provider store={xxxx}></Provider>,将store挂载在contex上
  render() {
    return (
      <Context.Provider value={{ store: this.props.store }}>
        {this.props.children} //子组件
      </Context.Provider>
    );
  }
}

Reducer 函数,它接受 Action 和当前 State 作为参数,返回一个新的 State,内容和之前的几乎差不多:

import reducer from "./reducers/counter.jsx";
// ./reducers/counter.jsx
export default function reducer(state = { counter: 0 }, action = {}) {
  const { counter } = state;
  const { type } = action;

  switch (type) {
    case "INCREASE":
      return { counter: counter + 1 };
    case "DECREASE":
      return { counter: counter - 1 };
    default:
      return { counter: 0 };
  }
}

React-Redux 的核心之一 connect 方法,用于从 UI 组件生成容器组件。connect 方法接受两个参数:mapStateToPropsmapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将 state 映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。

import App from "./store/app.jsx";
// ./store/app.jsx
import { connect } from "react-redux";

import App from "./../components/app.jsx";
import {
  increaseAction,
  decreaseAction,
  resetAction
} from "./../actions/counter.jsx";

// mapStateToProps用户自己定义需要的状态
const mapStateToProps = state => ({ counter: state.counter });

const mapDispatchToProps = dispatch => ({
  onIncreaseHandle: () => dispatch(increaseAction),
  onDecreaseHandle: () => dispatch(decreaseAction),
  onResetHandle: () => dispatch(resetAction)
});

export default connect(mapStateToProps, mapDispatchToProps)(App);

Action 的 type 属性:

// ./../actions/counter.jsx
export const increaseAction = { type: "INCREASE" };
export const decreaseAction = { type: "DECREASE" };
export const resetAction = { type: "RESET" };

接着,我们看一下熟悉的 App 组件应该怎么写:

// import App from "./../components/app.jsx";
import React from "react";

class App extends React.Component {
  render() {
    let {
      counter,
      onIncreaseHandle,
      onDecreaseHandle,
      onResetHandle
    } = this.props;
    return (
      <div>
        <h1>{counter}</h1>
        <button onClick={onIncreaseHandle}>+1</button>
        <button onClick={onDecreaseHandle}>-1</button>
        <button onClick={onResetHandle}>0</button>
      </div>
    );
  }
}

export default App;

前期做了许多工作,这里如同从父组件里获取 props 属性般获取、触发等行为,所有 store 里的 state 都通过 connect 方法给处理了:

connect(mapStateToProps, mapDispatchToProps)(App);

到这里,计数器基本的功能都好了,我的 Demo,阮一峰老师的 Demo,以及讲解的文章,Redux 入门教程(三):React-Redux 的用法让 react 用起来更得心应手——(react-redux)

You can’t perform that action at this time.