Redux 入门

安装

npm install --save redux@4.Xreact

使用以前

了解 Redux 的一些核心概念:npm

  • action
  • reducer
  • store

使用

引入

import { createStore } from 'redux';
// 或
const { createStore } = require('redux');

定义一些 action creators:

function increment() {
    return { type: 'INCREMENT' };
}

function decrement() {
    return { type: 'DECREMENT' };
}

定义一个 reducer,用来根据 action 的 type 生成新的 store:

function counter(state = 0, action) {
    switch(action.type) {
    case 'INCREMENT':
        return state + 1;
    case 'DECREMENT':
        return state - 1;
    default :
        return state;
    }
}

根据上面定义的 reducer 建立 store:

const store = createStore(counter);

模拟 action:

let currentValue = store.getState();

const listener = () => {
    const previousValue = currentValue;
    currentValue = store.getState();
    console.log(` 以前的值:${previousValue},如今的值:${currentValue}`);
};

// 订阅监听函数,动做分发后回调
store.subscribe(listener);

// 分发动做
store.dispatch(increment());
store.dispatch(increment());
store.dispatch(decrement());

结果:

使用 react-redux 与 React 集成

安装

npm install --save react-redux@5.X react@16.X react-dom@16.Xredux

使用以前

先定义一些 React 组件:dom

// Counter.js
import React from 'react';
import { connect } from 'react-redux';
import * as ActionCreators from './ActionCreators';

function Counter({value, increment, decrement}) {
  return (
    <p>
      Click: {value} times {' '}
      <button onClick={increment} >+</button>{' '}
      <button onClick={decrement} >-</button>{' '}
    </p>
  );
}

export default connect(
  state => ({ value: state}),
  ActionCreators
)(Counter);

ActionCreators.js 文件中定义动做建立函数:ide

// ActionCreators.js
export function increment() {
  return { type: 'INCREMENT' };
}

export function decrement() {
  return { type: 'DECREMENT' };
}

使用 react-redux

// App.js
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import Counter from './Counter';

// ... 省略上面已经定义好的 reducer 和 store

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

能够看到,咱们使用了一个 react-redux 提供的 Provider 组件包裹了咱们须要传入 state 的组件(即 Counter),而且在将 store 传入。在 Counter 中使用 react-redux 提供的 connect 将 Counter 组合成了一个高阶组件,将 state 和 action 传入了 Counter 中的 props,这样咱们就能够在 Counter 组件中使用 state 和分发 action 了,能够直接经过 action creators 发起 action,跳过了 dispatch 这个冗余的过程,由于 react-redux 中的 connect 已经帮咱们作过了。函数

结果

react-redux

用后思考

固然,这个例子很是简单,根本不须要用到 redux,由于这个例子只有一个组件。若是你有过使用 props 来层层嵌套传递父级容器组件的 state 给子级展现组件的话,你必定很是厌恶这种不那么优雅的写法,不过使用 react-redux 就不须要这么麻烦了,咱们只须要使用 react-redux 提供的 connect 将组件组合成一个高阶组件导出,便可在子级展现组件内部经过 props 使用父级容器组件的 state,而父级容器组件的 state 由 redux 中的 store 来提供。例如,咱们将 App.js 改为多层嵌套的组件:ui

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

function SomeComponent(props) {
  return (
    <div>
      <h1>SomeComponent</h1>
      <OtherComponent />
    </div>
  );
}

function OtherComponent(props) {
  return (
    <div>
      <h2>OtherComponent</h2>
      <Counter />
    </div>
  );
}

上述组件应该在各自独立的文件中定义,为了节省篇幅,所以我把它们都写在 App.js 这个文件中。spa

结果

react-redux

能够看到,咱们嵌套了两层组件,可是 Counter 组件不须要层层嵌套来获取祖先级组件的 state,咱们只须要将全部的 state 提取到 Provider 组件中,而后使用 connect 将子级展现组件组合成高阶组件,便可各子级展现组件之间共享使用父级容器组件的 state,避免了丑陋的嵌套过多。code

咱们学到了什么❓

经过使用 redux 和 react-redux 来集中管理 state,以更加优雅的方式传递父级容器组件的 state。rem

相关文章
相关标签/搜索