摘要:這里的其實不需要自己寫,已經(jīng)有好的實現(xiàn)了引入修改組件完整源碼組件資源源碼
0x000 概述
前面雖然簡單的講了如何在react中集成redux,但是那只是簡單的講講而已,這一章將會仔細(xì)講講如何在react中使用reudx
0x001 問題分析查看前邊的栗子:
import {createStore} from "redux" import React from "react" import ReactDom from "react-dom" //reducer const counter = (state = 0, action) => { switch (action.type) { case ACTION_INCREMENT: return state + 1 case ACTION_DECREMENT: return state - 1 default: return state } } // action const ACTION_INCREMENT = "INCREMENT" const ACTION_DECREMENT = "DECREMENT" // action creator const increment = () => ({ type: ACTION_INCREMENT }) const decrement = () => ({ type: ACTION_DECREMENT }) // store const store = createStore(counter) // react // // 組件 class App extends React.Component { constructor() { super() // 初始化 state this.state = { counter: 0 } // 監(jiān)聽 store 變化, store 變化的時候更新 counter this.unSub=store.subscribe(() => { this.setState({ counter: store.getState() }) }) } // 組件銷毀的時候取消訂閱 componentWillUnmount(){ this.unSub() } render() { return} } ReactDom.render({this.state.counter}
, document.getElementById("app") )
為了讓組件可以響應(yīng)redux的變化,我們寫了一些代碼:
.... // 監(jiān)聽 store 變化, store 變化的時候更新 counter this.unSub=store.subscribe(() => { this.setState({ counter: store.getState() }) }) .... // 組件銷毀的時候取消訂閱 componentWillUnmount(){ this.unSub() }
如果我們有大量的組件需要綁定redux,那么寫這些代碼就顯得非常冗余了
這一章要做的事就是優(yōu)化掉這個東西
這里用了一個react的HOC,參數(shù)是一個組件,返回值也是一個組件,但是返回的組件被添加了一個props,也就是state。connect方法為每個組件添加了響應(yīng)store數(shù)據(jù)變化的能力,在store.dispatch調(diào)用的時候,會修改組件的props,讓組件重繪,從而達(dá)到react組件和redux綁定但是又不需要寫太多樣板代碼
connect
const connect = (WrappedComponent) => { return class Control extends React.Component { constructor() { super() this.state = { state: 0 } this.unSub = store.subscribe(() => { this.setState({ state: store.getState() }) }) } componentWillUnmount() { this.unSub() } render() { return} } }
完整源碼
import {createStore} from "redux" import React from "react" import ReactDom from "react-dom" //reducer const counter = (state = 0, action) => { switch (action.type) { case ACTION_INCREMENT: return state + 1 case ACTION_DECREMENT: return state - 1 default: return state } } // action const ACTION_INCREMENT = "INCREMENT" const ACTION_DECREMENT = "DECREMENT" // action creator const increment = () => ({ type: ACTION_INCREMENT }) const decrement = () => ({ type: ACTION_DECREMENT }) // store const store = createStore(counter) const connect = (WrappedComponent) => { return class Control extends React.Component { constructor() { super() this.state = { state: 0 } this.unSub = store.subscribe(() => { this.setState({ state: store.getState() }) }) } componentWillUnmount() { this.unSub() } render() { return0x003 加強connect方法,消除訂閱整個state樹的影響} } } // 子組件 class SubCom extends React.Component { render(){ return {this.props.state}
} } // 包裹這個組件 let ReduxSubCom=connect(SubCom) // react 組件 class App extends React.Component { constructor() { super() } render() { return} } // 包裹組件 let ReduxApp = connect(App) ReactDom.render(, document.getElementById("app") )
雖然已經(jīng)實現(xiàn)了將state和組件綁定,但是我們綁定的是整個state,如果state樹很大并且組件很多,那這個無畏的性能消耗太兇了。
修改redux結(jié)構(gòu)
const counter = (state = {counter: 0, num: 0}, action) => { switch (action.type) { case ACTION_INCREMENT: return {...state, ...{counter: ++state.counter}} case ACTION_DECREMENT: return {...state, ...{counter: --state.counter}} default: return state } }
修改connect方法,返回一個函數(shù),并修改props傳參:
const connect = (mapStateToProps) => { return (WrappedComponent) => class Control extends React.Component { constructor() { super() this.state = { state: {} } this.unSub = store.subscribe(() => { let state = mapStateToProps(store.getState()) this.setState({ state: state }) }) } componentWillUnmount() { this.unSub() } render() { return} } }
修改APP組件中的props訪問方式
class App extends React.Component { constructor() { super() } componentWillReceiveProps(nextProps) { console.log(nextProps) } render() { return} }{this.props.counter}
修改connect調(diào)用
let ReduxApp = connect((state) => { return { counter: state.counter } })(App)0x004: 加強connect,讓代碼中不再調(diào)用store.dispatch,不在依賴redux
修改connect方法,除了吧state映射到props上,也把dispatch給映射上去了,這樣組件就感受不到redux的存在了
const connect = (mapStateToProps, mapDispatchToProps) => { return (WrappedComponent) => class Control extends React.Component { constructor() { super() // 第一次初始化 let props = mapStateToProps(store.getState()) let actions = mapDispatchToProps(store.dispatch) this.state = { props: {...props,...actions} } this.unSub = store.subscribe(() => { // 變化的時候再次計算 let props = mapStateToProps(store.getState()) let actions = mapDispatchToProps(store.dispatch) this.setState({ props: {...props,...actions} }) }) } componentWillUnmount() { this.unSub() } render() { return} } }
修改connect調(diào)用,將dispatch映射到組件上
let ReduxApp = connect( (state) => { return { counter: state.counter } }, (dispatch) => { return { increment: () => dispatch(increment()), decrement: () => dispatch(decrement()), } } )(App)
修改App組件,不再使用store.dispatch,而是使用connect傳遞過來的dispatch,讓組件不依賴redux
class App extends React.Component { constructor(props) { super() } render() { const {counter,increment,decrement}=this.props return} }{counter}
完整源碼
import {createStore} from "redux" import React from "react" import ReactDom from "react-dom" //reducer const counter = (state = {counter: 0, num: 0}, action) => { switch (action.type) { case ACTION_INCREMENT: return {...state, ...{counter: ++state.counter}} case ACTION_DECREMENT: return {...state, ...{counter: --state.counter}} default: return state } } // action const ACTION_INCREMENT = "INCREMENT" const ACTION_DECREMENT = "DECREMENT" // action creator const increment = () => ({ type: ACTION_INCREMENT }) const decrement = () => ({ type: ACTION_DECREMENT }) // store const store = createStore(counter) const connect = (mapStateToProps, mapDispatchToProps) => { return (WrappedComponent) => class Control extends React.Component { constructor() { super() // 第一次初始化 let props = mapStateToProps(store.getState()) let actions = mapDispatchToProps(store.dispatch) this.state = { props: {...props,...actions} } this.unSub = store.subscribe(() => { // 變化的時候再次計算 let props = mapStateToProps(store.getState()) let actions = mapDispatchToProps(store.dispatch) this.setState({ props: {...props,...actions} }) }) } componentWillUnmount() { this.unSub() } render() { return0x004 reat-redux} } } // react 組件 class App extends React.Component { constructor(props) { super() } render() { const {counter,increment,decrement}=this.props return } } let ReduxApp = connect( (state) => { return { counter: state.counter } }, (dispatch) => { return { increment: () => dispatch(increment()), decrement: () => dispatch(decrement()), } } )(App) ReactDom.render({counter}
, document.getElementById("app") )
以上效果就和上一章的效果一致,是一個counter,在這里我們一步一步去除了樣板代碼,并將redux從組件中移除,如果只看App組件,根本感覺不到redux的存在,但redux又確實存在,如果有一天你要去掉redux,就可以做到不影響組件了。這里的connect其實不需要自己寫,已經(jīng)有好的實現(xiàn)了:react-redux
// 引入`react-redux` import {Provider, connect} from "react-redux" // 修改組件 ReactDom.render(, document.getElementById("app") )
完整源碼
import {createStore} from "redux" import React from "react" import ReactDom from "react-dom" import {Provider, connect} from "react-redux" //reducer const counter = (state = {counter: 0, num: 0}, action) => { switch (action.type) { case ACTION_INCREMENT: return {...state, ...{counter: ++state.counter}} case ACTION_DECREMENT: return {...state, ...{counter: --state.counter}} default: return state } } // action const ACTION_INCREMENT = "INCREMENT" const ACTION_DECREMENT = "DECREMENT" // action creator const increment = () => ({ type: ACTION_INCREMENT }) const decrement = () => ({ type: ACTION_DECREMENT }) // store const store = createStore(counter) // react 組件 class App extends React.Component { constructor(props) { super() } render() { const {counter, increment, decrement} = this.props return0x005 資源} } let ReduxApp = connect( (state) => { return { counter: state.counter } }, (dispatch) => { return { increment: () => dispatch(increment()), decrement: () => dispatch(decrement()), } } )(App) ReactDom.render({counter}
, document.getElementById("app") )
源碼
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108509.html
摘要:概述之前寫的所有關(guān)于的文章都是純粹的,是和框架無關(guān)環(huán)境無關(guān)的,所以我沒有將和一起講,為的是吧和分開,作為獨立的個體來分析,提現(xiàn)的是一種思想,而不是一個思維定式。而現(xiàn)在我們可以嘗試在中來使用了。 0x000 概述 之前寫的所有關(guān)于redux的文章都是純粹的redux,是和框架無關(guān)、環(huán)境無關(guān)的redux,所以我沒有將redux和react一起講,為的是吧redux和react分開,作為獨立...
摘要:概述這一章終于大集成了集成源碼效果說明集成主要是用到庫集成源碼效果說明主要用到庫,是針對庫在環(huán)境下的封裝組件,注入等屬性接管跟組件指定路由和組件的對應(yīng)關(guān)系集成源碼引入相關(guān)的包和鏈接組件效果說明主要用到庫都是用的接 0x000 概述 這一章終于大集成了 0x001 集成react 源碼 import React from react import ReactDom from rea...
摘要:接下來演示不變性打開終端并啟動輸入。修改代碼如下我們使用在控制臺中打印出當(dāng)前的狀態(tài)。可以在控制臺中確認(rèn)新的商品已經(jīng)添加了。修改和文件最后,我們在中分發(fā)這兩個保存完代碼之后,可以在瀏覽器的控制臺中檢查修改和刪除的結(jié)果。 典型的Web應(yīng)用程序通常由共享數(shù)據(jù)的多個UI組件組成。通常,多個組件的任務(wù)是負(fù)責(zé)展示同一對象的不同屬性。這個對象表示可隨時更改的狀態(tài)。在多個組件之間保持狀態(tài)的一致性會是一...
摘要:提供了完整的環(huán)境,并且支持自定義域名指向,動態(tài)計算資源調(diào)整,可以完成各種應(yīng)用的開發(fā)編譯與部署。 react 新特性 react16 Context 算法相關(guān) 圖解排序算法(二)之希爾排序 微信小程序 微信小程序組件化的解決方案移動端尺寸基本知識 瀏覽器 前端必讀:瀏覽器內(nèi)部工作原理瀏覽器緩存原理解讀瀏覽器加載css和js及dom解析之間的關(guān)系瀏覽器緩存 CSS學(xué)習(xí) 移動web開發(fā)布局入...
閱讀 4709·2021-11-18 13:23
閱讀 902·2021-09-22 15:24
閱讀 1924·2021-09-06 15:00
閱讀 2624·2021-09-03 10:30
閱讀 1284·2021-09-02 15:15
閱讀 2066·2019-08-30 15:54
閱讀 3034·2019-08-30 15:44
閱讀 1455·2019-08-29 15:12