React 使用 Redux 基本範例

tags: Web React Redux
category: Front-End
description: React 使用 Redux 基本範例
created_at: 2021/06/29 00:00:00

cover image

範例目的

最基礎的範例,建立兩個按鈕,分別遞增state與遞減state

事前準備

  • 裝好 Node.js

先建立你的 React Project

$ npx create-react-app redux-app

安裝套件

$ npm install redux react-redux --save

整理目錄

<src>
  <pages>
    <components>
      ControlPanel.js
    App.js
  <redux>
    <reducers>
      index.js
    actions.js
    actionTypes.js
    store.js
  index.js

設定 action types

檔案路徑: src/redux/actionTypes.js

定義我有哪些action的key常數

export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';

設定 reducer

檔案路徑: src/redux/reducers/index.js

開始為每個action決定要做什麼

import {INCREMENT, DECREMENT} from "../actionTypes";

const reducer = (state, action) => {
    switch (action.type) {
        case INCREMENT:
            return {...state, count: state.count + 1};
        case DECREMENT:
            return {...state, count: state.count - 1};
        default:
            return state;
    }
}


export default reducer;

建立store

檔案路徑: src/redux/store.js

createStore(reducer, {初始state})

import {createStore} from "redux";
import reducer from "./reducers";

export default createStore(reducer, {count: 0});

action.js

檔案路徑: src/redux/action.js

定義action, 傳回的資料會讓reducer的action接住

import {DECREMENT, INCREMENT} from "./actionTypes";

export const increment = () => ({type: INCREMENT});
export const decrement = () => ({type: DECREMENT});

修改index.js

檔案路徑: src/index.js

在外層包住一個<Provider>並帶入store屬性,裡面的component如果需要state會帶入props中

import React from 'react';
import ReactDOM from 'react-dom';
import App from './pages/App';
import {Provider} from "react-redux";
import store from "./redux/store";

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

修改App元件

檔案路徑: src/pages/App.js

import {connect} from "react-redux";
import ControlPanel from "./components/ControlPanel";

function App(props) {
    return (
        <div className="App">
            {props.count}
            <br/>
            <ControlPanel></ControlPanel>
        </div>
    );
}

// 設定我需要從state拿哪些props
const mapStateToProps = state => ({
    count: state.count
});

export default connect(mapStateToProps)(App);

修改ControlPanel元件

檔案路徑: src/pages/components/ControlPanel.js

import {connect} from "react-redux";
import {decrement, increment} from "../../redux/actions";

function ControlPanel(props) {
    const incrementHandler = e => {
        props.increment();
    };

    const decrementHandler = e => {
        props.decrement();
    };

    return (
        <>
            <button onClick={incrementHandler}>increment</button>
            <br/>
            <button onClick={decrementHandler}>decrement</button>
        </>
    )
}

// 設定我需要哪些dispatch,會設定到props中
const mapDispatchToProps = {increment, decrement};

export default connect(null, mapDispatchToProps)(ControlPanel);

完成! 因為是範例,所以沒有多做太多解釋,大概可以從程式碼找出關聯。




最後更新時間: 2021年06月29日.