redux和react-redux的使用詳解

來源:互聯網
上載者:User

我自己的理解redux就跟vue中的vuex差不多,都是資料管理器,話不多說,我們從經典的計數器案例開始講解

使用redux實現計數器

建立如下的react項目,我習慣把每一個模組分塊,才有這麼多檔案,當然你也可以寫在一個js檔案中,這不是重點

首先我們看一下項目的入口檔案index.js

import 'core-js/fn/object/assign';import React from 'react';import ReactDOM from 'react-dom';import Counter from './components/Counter'; //引入計數器件import {createStore} from 'redux'; //通過解構賦值得到createStore,為store的建立做準備import reducer from './reducers/index' //引入reducer純函數 該函數,根據action的type不同結合舊的state返回新的statelet store = createStore(reducer); //建立redux的核心 store store我會在後面進行詳細的解答import {numAdd,numDel} from './actions/index'; //引入action函數,觸發什麼操作,就根據操作怎樣改變值// Render the main component into the dom//這裡使用Redducer變數來定義ReactDOM中的render函數,是方便store中state更新之後,頁面的渲染const Redducer = () =>{  ReactDOM.render(    <Counter           value={store.getState()}       add ={()=>store.dispatch(numAdd())}      del ={()=>store.dispatch(numDel())}    ></Counter>,    document.getElementById('app')  );};// value={store.getState()} 給展示組件Counter傳遞資料 這裡的store.getState()得到的值,就是store建立過程中reducer純函數裡面的初始state值// ()=>store.dispatch(numAdd())和()=>store.dispatch(numDel()) 定義函數傳遞給展示組件Counter//store.dispatch(參數)會傳遞一個對象作為參數例如{type:"add"},調用reducer純函數,實現store中的state的更新Redducer();//該函數執行,就初始化了頁面store.subscribe(Redducer);//store.subscribe()用來監聽store中大的state是否發生改變,如果發生改變,就重新渲染頁面,所以才跟Redducer()進行綁定

在看純函數reducer,至於為什麼redux負責state編輯的函數統稱reducer,我自己的猜測是根據es5中的reduce方法有關(純屬瞎猜測,切勿當真)

const reducer = (state=0,action)=>{  switch (action.type){    case 'add':      return state+1;    case 'del':      return state-1;    default:      return state  }};//定義store的state = 0,action接受的值就是store.dispatch(numAdd())中通過numAdd()函數的到的一個對象//由於前面在得到store的時候 該函數跟redux中的createStore進行了綁定 也就是這一句代碼 let store = createStore(reducer)//所以通過這裡就可以改變store的state值,所以說現在可以的理解reducer為什麼是一個純函數了吧export default reducer;

在看actions中的匯出函數

export const numAdd = ()=>{  return{    type:"add"  }};export const numDel = ()=>{  return{    type:"del"  }}//匯出兩個函數,每一個函數返回一個包含type屬性的對象(注意ation中type是必須的,其他的屬性可以自行添加),可以通過解構賦值得到每一個//的函數,就像入口檔案index.js中的這一句代碼 import {numAdd,numDel} from './actions/index';

最後看展示組件Counter

import React from 'react';//函數返回組件的話,就是解構賦值擷取資料// const Counter = ({ value, add, del })=>{//   return(//    <div>//      <p style={{color:'red'}}>//        點擊次數{value}//      </p>//      <button onClick={add}>加一</button>//      <button onClick={del}>減一</button>//    </div>//   )// };//class返回組件的話,就是直接擷取當前組件自身的屬性,就可以擷取到自己想要的資料class Counter extends React.Component {  render() {    return (      <div>        <p style={{color: 'red'}}>          點擊次數{this.props.value}        </p>        <button onClick={this.props.add}>加一</button>        <button onClick={this.props.del}>減一</button>      </div>    )  }}export default Counter;

在這裡我使用了兩種方式來建立組件,第一種通過函數的方式建立的組件,要擷取在入口檔案index.js中傳過來的資料,只能通過形參解構賦值的到資料,第二種通過class建立的組件只能通過組件自身的屬性,來擷取資料,當然也可以通過解構賦值來得到自己想要的資料,代碼如下

class Counter extends React.Component {  render() {    let {value,add,del} = this.props;    return (      <div>        <p style={{color: 'red'}}>          點擊次數{value}        </p>        <button onClick={add}>加一</button>        <button onClick={del}>減一</button>      </div>    )  }

 

綜上所有的代碼就可以實現了簡單的計數器的功能,這就是redux最基本的使用方法,提示:redux和reat-redux需要自己安裝,最好使用--save來安裝

 

接下來就是使用redux和react-redux來實現計數器

且看代碼

import React, { Component } from 'react' //引入reactimport PropTypes from 'prop-types' //引入限制UI組件(展示組件)屬性限制import ReactDOM from 'react-dom' //引入react-dom相關的對象import { createStore } from 'redux' //引入reduximport { Provider, connect } from 'react-redux'//引入react配套的redux// 建立react組件(或者是虛擬節點)class Counter extends Component {  render() {    const { value, onIncreaseClick } = this.props;    //通過解構賦值得到相應的屬性裡面的值    //在這裡Counter是UI組件(展示組件)其屬性是其外面的容器組件中的state是通過react-redux中的connect操作之後傳遞過來的    return (      <div>        <span>{value}</span>        <button onClick={onIncreaseClick}>Increase</button>        {/*通過點擊事件觸發綁定的屬性,很明顯,在這裡onIncreaseClick是一個方法或者是一個對象的key值,其映射的value值是一個函數*/}      </div>    )  }}//對展示組件中屬性各個值得類型進行限制 不合符規則會報錯Counter.propTypes = {  value: PropTypes.number.isRequired, //屬性對象中的value必須是number類型還有必須有值  onIncreaseClick: PropTypes.func.isRequired //屬性對象中的onIncreaseClick必須是函數還有必須有值};// 這裡定義的是一個action對象,我的理解就是跟vuex中actions的作用差不多,發送不同的動作名稱,通過配套其他函數的監聽//實現容器組件的狀態(state)的改變,只不過vuex中的actions是發送動作名,redux是根據actions對象中的type的值不同,進行不同的操作const increaseAction = { type: 'increase' };// 定義reducer純函數,reducer函數的作用就是,根據傳過來的action和舊state的狀態值//然後根據action的type的值進行不同的操作,進行新的state的返回,從而達到UI組件(展示組件)的重新渲染function counter(state = { count: 0 }, action) {  const count = state.count;  switch (action.type) {    case 'increase':      return { count: count + 1 };    default:      return state  }}// 建立store對象,可以說store是redux的核心,因為根據redux的設計理念,//對state的操作都是根據store中的各種方法實現的,便於管理//在這裡規定使用redux中的createStore和reducer純函數結合來得到我們想要的storeconst store = createStore(counter);//mapStateToProps是connect的第一個參數//根據名稱我們知道是把之前reducer純函數中的state(狀態)和展示組件的props(屬性)進行映射function mapStateToProps(state) {  return {    value: state.count  }}// mapDispatchToProps是connect的第二個參數//根據名稱我們可以知道是把reducer純函數中之前store中的dispatch方法和展示組件的props(屬性)進行映射function mapDispatchToProps(dispatch) {  return {    onIncreaseClick: () => dispatch(increaseAction)  }}// 這裡定義App為react-redux設計理念中的容器組件//通過connect中傳遞參數和展示組件Counter相結合得出相應的容器組件App//這裡的容器組件App裡麵包含了展示組件Counterconst App = connect(  mapStateToProps,  mapDispatchToProps)(Counter);//向目標元素渲染容器組件App//這裡的組件Provider是一個react-redux中特殊的組件//注意: 1. Provider中有且只有一個子組件(這裡就是App容器組件,不一定是容器組件,根據自己的業務需求自己操作)//      2. 使用Provider組件的好處是,只需要給Provider組件設定屬性,那麼其子組件和其子組件中的子組件都可以直接使用其對應的屬性//      3. 避免了組件嵌套之後一個一個傳遞的複雜操作ReactDOM.render(  <Provider store={store}>    <App />  </Provider>,  document.getElementById('app'))

在這裡就完成了redux和react-redux的結合使用,通過自己的學習,我發現了編程思想是多麼的重要,我感歎於react-redux這種思想的深度,整體感覺乾淨,使得展示組件和容組件既相互分離又有一定的結合,兼職就是藕斷絲連,但是又不會違背組件分離的思想,簡直就是強大

,好了基礎的redux和react-redux的講解就到此結束了,後面我還會寫出redux非同步編程的理解,畢竟現在的都是同步實現

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.