1. 程式人生 > >Redux入門0x106: `react`、`vue`、`原生 js`整合`redux`

Redux入門0x106: `react`、`vue`、`原生 js`整合`redux`

0x000 概述

之前寫的所有關於redux的文章都是純粹的redux,是和框架無關、環境無關的redux,所以我沒有將reduxreact一起講,為的是吧reduxreact分開,作為獨立的個體來分析,redux提現的是一種思想,而不是一個思維定式。而現在我們可以嘗試在react中來使用了。

0x001 react整合redux栗子-counter

  • 原始碼
import {createStore} from 'redux'
import React from 'react'
import ReactDom from 'react-dom'

//reducer
const counter = (state = 0, action) => {
    switch (action.type) {
        case ACTION_INCREMENT:
            return state + 1
        case ACTION_DECREMENT:
            return state - 1
        default:
            return state
    }
}
// action
const ACTION_INCREMENT = 'INCREMENT'
const ACTION_DECREMENT = 'DECREMENT'
// action creator
const increment = () => ({
    type: ACTION_INCREMENT
})
const decrement = () => ({
    type: ACTION_DECREMENT
})

// store
const store = createStore(counter)

// 元件
class App extends React.Component {
    constructor() {
        super()
        // 初始化 state
        this.state = {
            counter: 0
        }
        // 監聽 store 變化, store 變化的時候更新 counter
        store.subscribe(() => {
            this.setState({
                counter: store.getState()
            })
        })
    }
    // 元件銷燬的時候取消訂閱
    componentWillUnmount(){
        this.unSub()
    }
    render() {
        return <div>
            <p>{this.state.counter}</p>
            <button
                onClick={() => {
                    store.dispatch(increment())
                }}>+
            </button>
            <button
                onClick={() => {
                    store.dispatch(decrement())
                }}>-
            </button>
        </div>
    }
}

ReactDom.render(
    <App/>,
    document.getElementById('app')
)
  • 效果

圖片描述

0x002 原生整合 redux

  • src/index.html

    <!doctype html>
    <html>
    <head>
        <title>React Study</title>
    </head>
    <body>
    <div id="app">
        <p id="counter">0</p>
        <button id="incrementBtn">+</button>
        <button id="decrementBtn">-</button>
    </div>
    </body>
    </html>
  • src/index.js

    import {createStore} from 'redux'
    //reducer
    const counter = (state = 0, action) => {
        switch (action.type) {
            case ACTION_INCREMENT:
                return state + 1
            case ACTION_DECREMENT:
                return state - 1
            default:
                return state
        }
    }
    // action
    const ACTION_INCREMENT = 'INCREMENT'
    const ACTION_DECREMENT = 'DECREMENT'
    // action creator
    const increment = () => ({
        type: ACTION_INCREMENT
    })
    const decrement = () => ({
        type: ACTION_DECREMENT
    })
    
    // store
    const store = createStore(counter)
    
    // 初始化一些 dom 變數
    let counterP = document.getElementById('counter')
    let incrementBtn = document.getElementById('incrementBtn')
    let decrementBtn = document.getElementById('decrementBtn')
    
    // 監聽變化, 在 store 變化的時候修改計數器顯示
    store.subscribe(() => {
        counterP.innerText = store.getState()
    })
    // 新增點選事件, 當+被點選的時候修改 state
    incrementBtn.onclick = () => {
        store.dispatch(increment())
    }
    // 新增點選事件, 當-被點選的時候修改 state
    decrementBtn.onclick = () => {
        store.dispatch(decrement())
    }
    
  • 效果和上圖一致

0x003 vue整合redux

  • 原始碼:

    <template>
        <div id="app">
            <p>{{counter}}</p>
            <button v-on:click="increment">+</button>
            <button v-on:click="decrement">-</button>
        </div>
    </template>
    
    <script>
        import {createStore} from 'redux'
        //reducer
        const counter = (state = 0, action) => {
            switch (action.type) {
                case ACTION_INCREMENT:
                    return state + 1
                case ACTION_DECREMENT:
                    return state - 1
                default:
                    return state
            }
        }
        // action
        const ACTION_INCREMENT = 'INCREMENT'
        const ACTION_DECREMENT = 'DECREMENT'
        // action creator
        const increment = () => ({
            type: ACTION_INCREMENT
        })
        const decrement = () => ({
            type: ACTION_DECREMENT
        })
    
        // store
        const store = createStore(counter)
        export default {
            name: 'app',
            data: function () {
                return {
                    counter: 0
                }
            },
            created: function () {
                // 元件建立的時候監聽 store 變化, 更新到 data
                this.unSub=store.subscribe(() => {
                    this.counter = store.getState()
                })
            },
            beforeDestroy:function(){
                // 元件銷燬的時候取消訂閱
                this.unSub()
            },
            methods: {
                increment: function () {
                    store.dispatch(increment())
                },
                decrement: function () {
                    store.dispatch(decrement())
                }
            }
        }
    </script>
    
    <style>
    
    </style>
    
  • 效果和上圖一致

0x004 總結

redux是獨立的,就和reactvue一樣都是獨立的框架,如何組合他們是我們的選擇,而不是必然和唯一的,要讓框架成為我們的生產力工具,而不是束縛我們的存在。

0x005 資源