如何從零基礎(chǔ)搭建一個(gè)react redux hello world(二)

接著上一篇,來看看上一篇目錄結(jié)構(gòu)

Paste_Image.png

再來看看index.js,可以看到,只是引用了HelloWorld,雖然引用了reducers,但是并沒有用到,所以上一篇僅僅是寫了一個(gè)react的hello world,還沒有redux的概念在里面

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import  reducers from './reducer'
import HelloWorld from './components/helloWorld'

const store = createStore(reducers,{text:'hello world'})
const rootEl = document.getElementById('root')

const render = () => ReactDOM.render(
  <HelloWorld></HelloWorld>,
  rootEl
)

render()

本文將一步步介紹如何去添加redux,首先看看目錄結(jié)構(gòu)

Paste_Image.png

1.actions,理解成actions創(chuàng)建函數(shù)

import { CHANGE_TEXT } from '../actionsType'

export function changeText(text) {
  return {
    type: CHANGE_TEXT,
    payload: text
  }
}

定義了一個(gè)action,觸發(fā)CHANGE_TEXT,并把形參text賦值給payload,比較簡(jiǎn)單

2.actionsType,以常量定義action

export const CHANGE_TEXT = 'CHANGE_TEXT'

這個(gè)更簡(jiǎn)單,定義了一個(gè)action。當(dāng)應(yīng)用規(guī)模越來越大時(shí),建議使用單獨(dú)的模塊或文件來存放 action

3.components,展示組件庫,里面包含了一個(gè)helloWorld組件

import React, { Component, PropTypes } from 'react';
// @pureRender
export default class HelloWorld extends Component {
  constructor(props) {
    super(props);

    this.state = {};
  }
  
  componentWillReceiveProps(newProps){
    console.log(newProps)
  }
  render() {
    return (
      <div>
        <button onClick={()=>{this.props.onClick(Math.random())}}>change Text</button>
            <div>{this.props.text}</div>
      </div>
    )
  }
}

這是一個(gè)helloWorld組件,比較簡(jiǎn)單,從props中獲取了一個(gè)onClick和text

4.containers ,容器組件庫

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux';
import * as HelloWorldActions from '../actions/HelloWorld'
import HelloWorld from '../components/helloWorld'
// @pureRender
class App extends Component {
  constructor(props) {
    super(props);

    this.state = {};
  }
  componentDidMount() {
  }
  render() {
    const { helloChan, helloWorldActons } = this.props
    return (
      <div>
        <HelloWorld onClick={helloWorldActons.changeText} text=   {helloChan.text}></HelloWorld>
      </div>
    )
  }
}

const mapStateToProps = state => state
const mapDispatchToProps = dispatch => ({
  helloWorldActons: bindActionCreators(HelloWorldActions, dispatch)
});
export default connect(mapStateToProps, mapDispatchToProps)(App);

可以看見這個(gè)組件稍微有點(diǎn)復(fù)雜,其中用到了react-redux中的connect,redux中的bindActionCreators,來看看定義

connect

算了,還是不看定義了,比較難懂,可以理解成它是react和redux的連接器,而且它確實(shí)是。它接受兩個(gè)參數(shù)mapStateToProps,mapDispatchToProps,前者指定如何把當(dāng)前 Redux store state 映射到展示組件的 props 中,后者接收 dispatch()
方法并返回期望注入到展示組件的 props 中的回調(diào)方法。
看不懂是吧,實(shí)例講解下
首先,mapStateToProps中的參數(shù)state就是在定義reducer時(shí)的state,這個(gè)一會(huì)兒再講,首先看看state的結(jié)構(gòu)

{ text: 'hello world',name:'default name',config:{name:'張三',sex:'男'} }

如果如下定義mapStateToProps

const mapStateToProps = state => state

那么在打印當(dāng)前props時(shí),得到的結(jié)果如下

Paste_Image.png

如果如下定義mapStateToProps

const mapStateToProps = state => {return {config:state.helloChan.config}}

再來看看結(jié)果是什么

Paste_Image.png

看出區(qū)別了嗎?其實(shí)還是回歸到定義了,如何把當(dāng)前 Redux store state 映射到展示組件的 props 中。

bindActionCreators

再來看mapDispatchToProps,這個(gè)定義比較簡(jiǎn)單,將 action 作為 props 綁定到組件上,展開helloWorldActions,顯然它已經(jīng)將actions中的changeText綁定到了props上面

Paste_Image.png

'

此時(shí),假如修改actions中的代碼如下

import { CHANGE_TEXT } from '../actionsType'

export function changeText(text) {
  return {
    type: CHANGE_TEXT,
    payload: text
  }
}

export function changeTextTest(text) {
  return {
    type: CHANGE_TEXT,
    payload: text
  }
}

再看看截圖

Paste_Image.png

很明顯新增的changeTextTest已經(jīng)自動(dòng)綁定到props上

綜上所述,其實(shí)connect可以理解成自動(dòng)封裝了如何將state和actions綁定到組件上的一套邏輯,這下應(yīng)該明白了吧

5.reducers

首先,reducer有一個(gè)拆分的概念,可以將許多的reducer拆分成不同的文件,再通過combineReducers這個(gè)方法來進(jìn)行合并就行了,具體看一下代碼

import { combineReducers } from 'redux'
import helloWorld from './helloWorld'
import student from './student'

const todoApp = combineReducers({
  helloChan:helloWorld,
  student
})

export default todoApp;

有helloworld和student兩個(gè)reducer,可以通過combineReducers來合并,此時(shí)如果在connect中綁定state時(shí)直接這么寫

const mapStateToProps = state => {
  return state
}

我們來看看結(jié)果:

Paste_Image.png

看到了吧,多了student這個(gè)對(duì)象,其實(shí)一般情況下,一個(gè)container對(duì)應(yīng)一個(gè)reducer,所以改改綁定的代碼,如下

const mapStateToProps = state => {
  return { helloChan: state.helloChan }
}

再來看看結(jié)果,已經(jīng)沒有student了

Paste_Image.png

好了,本文就講到這里,看完整個(gè)教程,應(yīng)該比較清晰了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容