react中如何使用redux(react-redux)

首先聲明:redux僅僅做爲數據層框架,與react沒有直接的聯繫,他能夠應用與angular等其餘視圖層框架,或者直接導入使用react

redux核心分爲三部分:npm

store: redux的核心,暴露一些方法:getState()  dispatch()  subscrible(),store在整個應用中是惟一的,而且不能直接被修改,必須經過reduce修改redux

reduce:指定了應用狀態的變化如何響應 actions 併發送到 store 的瀏覽器

action:一個純JS對象,用來告訴reduce應該如何改變state,多數狀況下,會有一個 type 值,且會被定義成字符串常量併發

實例:框架

index.jsdom

import { createStore } from 'redux'
import reduce from './reduce'

const store = createStore(reduce, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

export default store

第二個參數ide

  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()函數

是給Redux開發者工具使用,添加後瀏覽器圖標會激活工具

reduce.js

const defaultState = {
    data: [
        'Racing car sprays burning fuel into crowd.',
        'Japanese princess to wed commoner.',
        'Australian walks 100km after outback crash.',
        'Man charged over missing wedding girl.',
        'Los Angeles battles huge wildfires.'
    ]
}

export default function reducer(state = defaultState, action){
    switch (action.type) {
        case 'ADD_RECORD':
            return Object.assign(
                {},
                state,
                {
                    data: [...state.data, action.text]
                }
            )
        case 'DEL_RECORD':
            var data = [...state.data]
            data.splice(action.index, 1)
            return Object.assign(
                {}, 
                state,
                {
                    data
                }
            )
        default: 
            return state
    }
}

每當調用store的dispatch方法,會執行reduce函數,reduce要求咱們返回一個state,reduce中有如下注意點:

  • 不能直接修改state
  • 不能執行有反作用的操做,如 API 請求和路由跳轉
  • 不能調用非純函數,如 Date.now() 或 Math.random()
  • 大多數狀況下,state的數據格式咱們能夠在初始化的時候能夠肯定,所以咱們能夠定義一個默認的

action

export const addRecord = function(text){
    return {
        type: 'ADD_RECORD',
        text
    }
}

export const delRecord = function(index){
    return {
        type: 'DEL_RECORD',
        index
    }
}

在須要修改store狀態的組件中觸發reduce修改state

import store from './store'
import { addRecord } from './store/action'

class Mycomponent extends Component
{
     ...

    addRecord(){
        //調用 dispatch ,參數爲一個 action
        store.dispatch(
            addRecord(this.state.inputVal)
        )
    }

    ...
}

在調用store組件訂閱store,實時響應

import store from './store'

class MyList extends React.Component{

    constructor(props){
        super(props)
        this.state = {
            ...store.getState()
        }
        store.subscribe(() => {
            this.setState({
                ...store.getState()
            })
        }) 
    }

    ...
}

reacte-redux

以上這種動手訂閱的方式十分繁瑣,所以推薦使用專爲react打造的第三庫 react-redux 去鏈接redux

使用:

npm install react-redux --save

 在index.js文件中引入 Provider 組件,將它包在最外層,把 store 做爲 prop 傳入 Provider

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

const Application = (
    <Provider store={store}>
        <App />
    </Provider>
)

ReactDOM.render(Application, document.getElementById('root'));

在應用組件中經過 connect 將組件與 store 關聯起來,而後能夠經過直接訪問 props 的方式訪問 store

import React from 'react'
import { connect } from 'react-redux'
import { delRecord } from './store/action'

class MyList extends React.Component{


    render(){
        return (
            <ul className="list-container">
                {this.props.data.map((item, index) => (
                    <li key={index} onClick={() => { this.props.delRecord(index) }}>{item}</li>
                ))}
            </ul>
        )
    }

}

const mapStateToProps = (state) => ({
    ...state
})

const mapDispatchToProps = (dispatch) => ({
    delRecord(index){
        dispatch(delRecord(index))
    }
})

export default connect(mapStateToProps, mapDispatchToProps)(MyList)

其中 connect 是一個高階函數

第一個參數 

mapStateToProps: 聲明將state與props對應的映射關係
mapDispatchToProps: 將須要對store修改操做聲明在這個對象中
相關文章
相關標籤/搜索