1. 程式人生 > >redux的簡單使用(例子演示)

redux的簡單使用(例子演示)

注意:以下每一步是按照redux由易到難的順序逐步進行的,從初步使用到react與redux的組合使用以及解耦的順序來的

安裝redux

npm install redux --save

1、redux的簡單使用

1、新建store

2、獲取狀態

3、派發事件

下邊程式碼簡單的演示此過程

在src下新建index.js,在index中編寫


import {createStore} from 'redux'

//1、新建store
//通過reducer建立
//根據老的state和action 生成新的state
function counter(state=0,action){
    switch(action.type){
        case 'addGun':
            return state+1
        case 'removeGun':
            return state-1
        default:
            return 10
    }
}
//1、新建store
const store = createStore(counter)
//2、獲取狀態
const init = store.getState()

function listener(){
    const current = store.getState()
    console.log(`現在的個數${current}`);
}
//每次派發事件之後,都會呼叫,進而獲取狀態
store.subscribe(listener)
//3、派發事件
store.dispatch({type:'addGun'})
store.dispatch({type:'addGun'})
store.dispatch({type:'removeGun'})



輸出:
現在的個數11
現在的個數12
現在的個數11

2、react與redux組合使用(手動連線)

  • 把store.dispatch方法傳遞給元件,內部可以呼叫修改狀態
  • subscribe訂閱render函式,每次修改都重新渲染
  • redux相關的內容,移動到單獨的檔案index.redux.js單獨管理
  • npm install redux-thunk --save 解決非同步請求的問題
    使用applyMiddleware開啟thunk中介軟體
在src下新建App.js、index.redux.js
在index.js中負責頁面結構的組建,store的建立
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
import { createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {counter} from './index.redux'
import {addGun,removeGun,addGunAsync} from './index.redux'
//applyMiddleware可以使用非同步操作
const store = createStore(counter,applyMiddleware(thunk))

function render(){
    ReactDom.render(<App store={store} addGun={addGun} removeGun={removeGun} addGunAsync={addGunAsync}/>,document.getElementById('root'))
}
render()
//監聽狀態的變化,每次重新渲染元件
store.subscribe(render)
在App.js中完成元件內容的編寫、頁面的渲染以及相關事件的派發
import React from 'react'

class App extends React.Component{
    // constructor(props){
    //     super(props)
    // }
    
    render(){
        //接收從父元件index.js中傳過來的store
        const store = this.props.store
        //獲取機槍數量狀態的變化
        const num = store.getState()
        //通過元件傳遞action,降低耦合度
        const addGun = this.props.addGun
        const removeGun = this.props.removeGun 
        const addGunAsync = this.props.addGunAsync 
        return(
            <div>
                <h2>現在有機槍{num}</h2>
                {/* 當點選按鈕時執行事件的派發,即呼叫action */}
                <button onClick={()=>store.dispatch(addGun())}>申請武器</button>
                <button onClick={()=>store.dispatch(removeGun())}>回收武器</button>
                <button onClick={()=>store.dispatch(addGunAsync())}>延遲迴收武器</button>
            </div>
        ) 
    }
}
export default App
index.redux.js 中負責store中對狀態變化的處理、action事件的編寫
const ADD_GUN = 'addGun'
const REMOVE_GUN = 'removeGun'

//store
export function counter(state=0,action){
    //當action被呼叫執行後,會到此處進行判斷,執行狀態的變化
    switch(action.type){
        case 'addGun':
            return state+1
        case 'removeGun':
            return state-1
        default:
            return 10
    }
}

//action
export function addGun(){
    return {type:ADD_GUN}
}
export function removeGun(){
    return {type:REMOVE_GUN}
}
export function addGunAsync(){
    return dispatch=>{
        setTimeout(()=>{
            dispatch(addGun())
        },2000)
    }
}

此種方法的弊端:如果有多個元件深層次傳遞store屬性,就會特別繁瑣,容易出錯,接下來我們就解決這個問題

3、redux使用的解耦(react與redux自動連線)

解決第二步的問題,我們安裝外掛
npm install react-redux --save 用於自動連線react與redux,不需要再呼叫subscribe方法

  • Provider 包裹在元件最外層,傳入store
  • Connect負責從外部獲取元件所需要的引數
  • Connect使用裝飾器的方式寫

裝飾器的安裝配置

參考文章

在index.js中負責頁面結構的組建,store的建立
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
import { createStore, applyMiddleware,compose} from 'redux'
import {Provider} from 'react-redux'
import thunk from 'redux-thunk'
import {counter} from './index.redux'


const store = createStore(counter,compose(
    applyMiddleware(thunk),
    //呼叫chrome中的redux外掛
    window.devToolsExtension?window.devToolsExtension():f=>f
))

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


在App.js中完成元件內容的編寫、頁面的渲染以及相關事件的派發
import React from 'react'
import {connect} from 'react-redux'
import {addGun,removeGun,addGunAsync} from './index.redux'

@connect(
    //需要的state屬性放到props中
    state=>({num:state}),
    //需要的方法,放到props中,自動dispatch
    {addGun,removeGun,addGunAsync}
)
class App extends React.Component{
    render(){
        
        return(
            <div>
                <h2>現在有機槍{this.props.num}</h2>
                {/* 當點選按鈕時執行事件的派發,即呼叫action */}
                <button onClick={this.props.addGun}>申請武器</button>
                <button onClick={this.props.removeGun}>回收武器</button>
                <button onClick={this.props.addGunAsync}>延遲申請武器</button>
            </div>
        ) 
    }
}
export default App
index.redux.js 中負責store中對狀態變化的處理、action事件的編寫
const ADD_GUN = 'addGun'
const REMOVE_GUN = 'removeGun'

//store
export function counter(state=0,action){
    //當action被呼叫執行後,會到此處進行判斷,執行狀態的變化
    switch(action.type){
        case 'addGun':
            return state+1
        case 'removeGun':
            return state-1
        default:
            return 10
    }
}

//action
export function addGun(){
    return {type:ADD_GUN}
}
export function removeGun(){
    return {type:REMOVE_GUN}
}
export function addGunAsync(){
    return dispatch=>{
        setTimeout(()=>{
            dispatch(addGun())
        },2000)
    }
}