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

相關文章
相關標籤/搜索