react+redux基礎用法


在學react的是,發現一旦我們封裝好了我們的組件,那么我們的項目就跟搭積木一樣簡單快速,可是我們發現了一個問題,在一個頁面往往會嵌套很多的組件,子組件必須要通過父組件傳遞參數才能渲染出數據,我們回想一下我們之前構建過的所有react應用,數據都是由最頂層父組件(頁面組件)一層層向下傳遞的。

這也是深層次的組件之間通訊困難的原因:數據的傳遞是單向的,子組件的數據只能就近獲取,但是真正的數據源卻離得太遠,沒有捷徑可以直接通知數據源更新狀態。

redux的出現改變了react的這種窘迫處境,它提供了整個應用的唯一數據源store,這個數據源是隨處可以訪問的,不需要靠父子相傳,並且還提供了(間接)更新這個數據源的方法,並且是隨處可使用的!

那么redux是如何工作的呢?這里我借用阮一峰react講解redux的圖來說明:
用戶看到的是能是我們的頁面,那么用戶如何跟我們的數據互動呢。首先初始化頁面,我們會渲染store里面的初始數據,
store 是redux提供的唯一數據源,它存儲了整個應用的state,並且提供了獲取state的方法,即 store.getState()
現在用戶點擊了某個按鈕,那么這個時候用戶就觸發了一個動作,稱之為action,action只是記錄了你剛才"做了什么動作",但是就是知道你干了這個事情,至於事情會發生什么作用,這個並不是你說的算的,就要引入我們的reducer了,如果說action就是你平常做的事,那么reducer就是國家的法律,根據你的事法律會給你相應的后果。
 
1.我們先看action
action是一個對象,記錄本次事件的類型,以便對應相應的結果,除了type屬性的其他屬性我們稱之為載荷(payload),除了type屬性外,其他屬性都是非必選的。
{
  type: 'CHANGE_LIST',
  data: [1,2,3,4]//這個是假數據,這里當做需要變成的數據,一般是后台拿到的
}

接下來我們要觸發這個事件

2.在redux中觸發這個事件的方式就是:

dispatch({
  type: 'CHANGE_LIST',
  data:[1,2,3,4] 
})

3.到這里我們觸發了事件,那么事件會產生啥效果呢,這里就提到我們的reducer

假設我們現在有一個列表組件,那么它的數據格式應該可以如下:

// store.getState()

{
  list: {
        products:['name','age','haha','gege']
  }
 
}

現在我們做了步驟2的action操作,那么reducer應該是這樣的:

function reducer(state, action) {
  switch (action.type) {
    case 'CHANGE_LIST':
    return {
      list: {
        products:action.data//修改給定的數據
      } 
    }
    default:
    return state  // 沒有匹配的action type,返回原來的state
  }
}
 
 到此為止我們知道這個操作會產生的效果就是原來的數組products從   ['name','age','haha','gege']  變成了  [1,2,3,4]。
4.拆分reducer
我們在react真實的項目肯定包含許多的組件,不能把所有組件的reducer寫在一個函數里面,這樣會顯得更復雜以及文件特別大,所以我們把上面的reducer改寫一下
function listReducer(state, action) {
  switch (action.type) {
    case 'CHANGE_LIST':
    return {
        products:action.data//修改給定的數據
    }
    default:
    return state  // 沒有匹配的action type,返回原來的state
  }
}

function reducer(state, action) {
  return {
    list: listReducer(state.list, action),
  }
}

可以看出達到的效果是一致的,剛好redux為reducer的合並提供了一個簡單的方法combineReducers,

function list(state, action) {
  switch (action.type) {
    case 'CHANGE_LIST':
    return {
      products:action.data
    }

    default:
    return state  // 沒有匹配的action type,返回原來的state
  }
}

function dialog(state, action) {
  switch (action.type) {
    case 'SHOW_DIALOG':
    return {
      status: true
    }

    case 'CLOSE_DIALOG':
    return {
      status: false
    }

    default:
    return state  // 沒有匹配的action type,返回原來的state
  }
}

export default combineReducers({
  list,
  dialog
})

5.生成store,在我們項目的入口文件app.js中:

import React, { Component, PropTypes } from 'react'
import ReactDom from 'react-dom'

// 引入redux
import { createStore, applyMiddleware } from 'redux'
import { Provider, connect } from 'react-redux'

// 引入reducer
import * as reducers from './redux/reducer.js'
import { combineReducers } from 'redux'

//引入組件
import Index from './component/index.js'

//把多個組件的reducer合成總的reducer
const reducer = combineReducers(reducers)

// 創建store,這個是整個應用唯一的
const store = createStore(reducer)

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

然后看看我們的Index組件是個啥樣子:

import React, { Component } from 'react'
import { connect } from 'react-redux'

import List from './list.js'

class Index extends Component {
    constructor(props) {
        super(props);
    }
    render () {
        return (
            <div>
                <List />
            </div>
        )
    }
}

function mapStateToProps(state) {
    return state  //對應本組件需要的傳入的props
}

export default connect(mapStateToProps)(Index)//關聯到store上

下面最重要的看看List組件:

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'

class List extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        var html = this.props.products.map(function(val,i) {
            return <li key={i}>{val}</li>
        })

        return (
            <div>
                <ul>
                    {html}
                </ul>
                <button onClick={this.props.change}>改變數組</button>
            </div>
        )
    }
}

function mapStateToProps(state) {
    var info = state.list

    return {
        products:info.products//對應本組件props需要的屬性products
    }
}

function mapDispatchToProps(dispatch) {
  return {
    change () {//這里change方法對應的是這個組件需要外部傳入的change方法
                dispatch({
                    type: 'CHANGE_LIST',
                    data:[1,2,3,4]
                })
            }
        })
      
    }
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(List)

 這里只是簡單介紹了redux基本知識,但是在實際的項目中如何應用呢,實際的項目react和redux結合如何搭建框架呢,這個下篇文章將會列出一個真實的項目。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM