簡(jiǎn)介:簡(jiǎn)單實(shí)現(xiàn)react-redux基礎(chǔ)api
react-redux api回顧
把store放在context里,所有子組件可以直接拿到store數(shù)據(jù)
使組件層級(jí)中的 connect() 方法都能夠獲得 Redux store 根組件應(yīng)該嵌套在中
ReactDOM.render(, rootEl ) ReactDOM.render( , document.getElementById("root") )
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
鏈接組件和數(shù)據(jù),把redux中的數(shù)據(jù)放到組件的屬性中
[mapStateToProps(state, [ownProps]): stateProps] (Function)
如果定義該參數(shù),組件將會(huì)監(jiān)聽(tīng) Redux store 的變化。任何時(shí)候,只要 Redux store 發(fā)生改變,mapStateToProps 函數(shù)就會(huì)被調(diào)用。該回調(diào)函數(shù)必須返回一個(gè)純對(duì)象,這個(gè)對(duì)象會(huì)與組件的 props 合并
如果你省略了這個(gè)參數(shù),你的組件將不會(huì)監(jiān)聽(tīng) Redux store
ownProps,則該參數(shù)的值為傳遞到組件的 props,而且只要組件接收到新的 props,mapStateToProps 也會(huì)被調(diào)用,被重新計(jì)算
mapStateToProps 函數(shù)的第一個(gè)參數(shù)是整個(gè)Redux store的state,它返回一個(gè)要作為 props 傳遞的對(duì)象。它通常被稱作 selector (選擇器)。 可以使用reselect去有效地組合選擇器和計(jì)算衍生數(shù)據(jù).
注意:如果定義一個(gè)包含強(qiáng)制性參數(shù)函數(shù)(這個(gè)函數(shù)的長(zhǎng)度為 1)時(shí),ownProps 不會(huì)傳到 mapStateToProps
const mapStateToProps = (state, ownProps) => { return { active: ownProps.filter === state.visibilityFilter } }
[mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function)
Object: 它的每個(gè)鍵名也是對(duì)應(yīng) UI 組件的同名參數(shù),鍵值應(yīng)該是一個(gè)函數(shù)(action creator),會(huì)被當(dāng)作 Action creator ,返回的 Action 會(huì)由 Redux 自動(dòng)發(fā)出, Function: 會(huì)得到dispatch和ownProps(容器組件的props對(duì)象)兩個(gè)參數(shù)(此時(shí)可能用到Redux 的輔助函數(shù) bindActionCreators())
省略這個(gè) mapDispatchToProps 參數(shù),默認(rèn)情況下,dispatch 會(huì)注入到你的組件 props 中,你可以this.props.dispatch調(diào)用
指定了該回調(diào)函數(shù)中第二個(gè)參數(shù) ownProps,該參數(shù)的值為傳遞到組件的 props,而且只要組件接收到新 props,mapDispatchToProps 也會(huì)被調(diào)用
eg:
connect(mapStateToProps, { hideAdPanel, pushAdData, })(AdPanel) function mapDispatchToProps(dispatch) { return { todoActions: bindActionCreators(todoActionCreators, dispatch), counterActions: bindActionCreators(counterActionCreators, dispatch) } }知識(shí)點(diǎn)補(bǔ)充 - React高階組件(Higher-Order Components)
高階組件就是一個(gè)函數(shù),且該函數(shù)接受一個(gè)組件作為參數(shù),并返回一個(gè)新的組件
高階組件就是一個(gè)沒(méi)有副作用的純函數(shù)
使用場(chǎng)景:兩個(gè)組件大部分代碼都是重復(fù)的+且更好的封閉性,不需要關(guān)注數(shù)據(jù)的獲取
import React, {Component} from "react" class Welcome extends Component { constructor(props) { super(props); this.state = { username: "" } } componentWillMount() { let username = localStorage.getItem("username"); this.setState({ username: username }) } render() { return (welcome {this.state.username}) } } export default Welcome; import React, {Component} from "react" class Goodbye extends Component { constructor(props) { super(props); this.state = { username: "" } } componentWillMount() { let username = localStorage.getItem("username"); this.setState({ username: username }) } render() { return (goodbye {this.state.username}) } } export default Goodbye;
welcome和goodbye組件相似,只能獲取的數(shù)據(jù)不一樣,用高階組件,提取公共部分
import React, {Component} from "react" export default (WrappedComponent) => { class NewComponent extends Component { constructor() { super(); this.state = { username: "" } } componentWillMount() { let username = localStorage.getItem("username"); this.setState({ username: username }) } render() { return} } return NewComponent } 簡(jiǎn)化welcome和goodbye import React, {Component} from "react"; import wrapWithUsername from "wrapWithUsername"; class Welcome extends Component { render() { return ( welcome {this.props.username}) } } Welcome = wrapWithUsername(Welcome); export default Welcome;
此時(shí),理解react-redux 的connect就好理解了
ConnectedComment = connect(mapStateToProps, mapDispatchToProps)(Component); // connect是一個(gè)返回函數(shù)的函數(shù)(就是個(gè)高階函數(shù)) const enhance = connect(mapStateToProps, mapDispatchToProps); // 返回的函數(shù)就是一個(gè)高階組件,該高階組件返回一個(gè)與Redux store // 關(guān)聯(lián)起來(lái)的新組件 const ConnectedComment = enhance(Component);provider實(shí)現(xiàn)
import React from "react" import ReactDOM from "react-dom" import { createStore, applyMiddleware, compose} from "redux" import thunk from "redux-thunk" import { counter } from "./index.redux" // import { Provider } from "react-redux" // 換成自己的Provider實(shí)現(xiàn) import { Provider } from "./self-react-redux" import App from "./App" const store = createStore(counter, compose( applyMiddleware(thunk), window.devToolsExtension ? window.devToolsExtension() : f => f )) ReactDOM.render( (), document.getElementById("root"))
./self-react-redux
import React from "react" import PropTypes from "prop-types" export function connect(){ } class Provider extends React.Component{ static childContextTypes = { store: PropTypes.object } getChildContext() { return { store: this.store } } constructor(props, context) { super(props, context) this.store = props.store } render(){ return this.props.children } }connect實(shí)現(xiàn)
demo
import React from "react" // import { connect } from "react-redux" import { connect } from "./self-react-redux" import { addGun, removeGun, addGunAsync } from "./index.redux" @connect( // 你要state什么屬性放到props里 state=>({num:state.counter}), // 你要什么方法,放到props里,自動(dòng)dispatch { addGun, removeGun, addGunAsync } ) class App extends React.Component{ render(){ return () } } export default App現(xiàn)在有機(jī)槍{this.props.num}把
./self-react-redux.js
// 高階組件的寫法 export function connect(maoStateToProps, mapStateToProps) { return function(WrapComponent) { return class ConnectComponent extends React.Component{ } } } import React from "react" import PropTypes from "prop-types" import { bindActionCreator } from "./self-redux" // 使用簡(jiǎn)寫形式 // connect負(fù)責(zé)鏈接組件,給到redux里的數(shù)據(jù)放在組件的屬性里 // 1. 負(fù)責(zé)接收一個(gè)組件,把state里的一些數(shù)據(jù)放進(jìn)去,返回一個(gè)組件 // 2. 數(shù)據(jù)變化的時(shí)候,能通知組件 export const connect = ( mapStateToProps = state => state, mapDispatchToProps ={} ) => (WrapComponent) => { return class ConnectComponent extends React.Component { static contextTypes = { store: PropTypes.object } constructor(props, context){ super(props, context) this.state = { props: {} } } // 2 實(shí)現(xiàn)了mapStateToProps componentDidMount() { const { store } = this.context store.subscribe(() => this.update()) this.update() } update() { const { store } = this.context // store.getState()這就是為什么mapStateToProps函數(shù)里面能拿到state const stateProps = mapStateToProps(store.getState()) // 方法不能直接給,因?yàn)樾枰猟ispatch /** function addGun() { return { type: ADD_GUN } } 直接執(zhí)行addGun() 毫無(wú)意義 要 addGun = () => store.dispatch(addGun()) 才有意義,其實(shí)就是把a(bǔ)ctionCreator包了一層 bindActionCreators在手寫redux api實(shí)現(xiàn)了 */ const dispatchProps = bindActionCreators(mapDispatchToProps, store.dispatch) // 注意state的順序問(wèn)題會(huì)覆蓋 this.setState({ props: { ...this.state.props, ...stateProps, ...dispatchProps, } }) } // 1 render() { return} } }
./self-redux.js
// creators: {addGun, removeGun, addGunAsync} // creators[v]:addGun(參數(shù)) // 返回:(參數(shù)) => dispatch(addGun(參數(shù))) function bindActionCreator(creator, dispatch) { return (...args) => dispatch(creator(...args)) } export function bindActionCreators(creators, dispatch) { let bound = {} Object.keys(creators).forEach( v => { let creator = creators[v] bound[v] = bindActionCreator(creator, dispatch) }) return bound } // 簡(jiǎn)寫 export function bindActionCreators(creators, dispatch) { return Object.keys(creators).reduce((ret, item) => { ret[item] = bindActionCreator(creators[item], dispatch) return ret }, {}) }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/98563.html
摘要:每個(gè)接受的和函數(shù)作為命名參數(shù),并返回一個(gè)函數(shù)。調(diào)用鏈中最后一個(gè)會(huì)接受真實(shí)的的方法作為參數(shù),并借此結(jié)束調(diào)用鏈。 簡(jiǎn)介: 手寫實(shí)現(xiàn)redux基礎(chǔ)api createStore( )和store相關(guān)方法 api回顧: createStore(reducer, [preloadedState], enhancer) 創(chuàng)建一個(gè) Redux store 來(lái)以存放應(yīng)用中所有的 state reduc...
摘要:的優(yōu)勢(shì)保證不可變每次通過(guò)操作的對(duì)象都會(huì)返回一個(gè)新的對(duì)象豐富的性能好通過(guò)字典樹對(duì)數(shù)據(jù)結(jié)構(gòu)的共享的問(wèn)題與原生交互不友好通過(guò)生成的對(duì)象在操作上與原生不同,如訪問(wèn)屬性,。 Immutable.js Immutable的優(yōu)勢(shì) 1. 保證不可變(每次通過(guò)Immutable.js操作的對(duì)象都會(huì)返回一個(gè)新的對(duì)象) 2. 豐富的API 3. 性能好 (通過(guò)字典樹對(duì)數(shù)據(jù)結(jié)構(gòu)的共享) Immutab...
摘要:前言是一個(gè)非常實(shí)用的狀態(tài)管理庫(kù),對(duì)于大多數(shù)使用庫(kù)的開(kāi)發(fā)者來(lái)說(shuō),都是會(huì)接觸到的。在使用享受其帶來(lái)的便利的同時(shí),我們也深受其問(wèn)題的困擾。只支持同步,讓狀態(tài)可預(yù)測(cè),方便測(cè)試。粗暴地級(jí)聯(lián)式刷新視圖使用優(yōu)化。 前言 Redux是一個(gè)非常實(shí)用的狀態(tài)管理庫(kù),對(duì)于大多數(shù)使用React庫(kù)的開(kāi)發(fā)者來(lái)說(shuō),Redux都是會(huì)接觸到的。在使用Redux享受其帶來(lái)的便利的同時(shí), 我們也深受其問(wèn)題的困擾。 redux...
摘要:前言前段時(shí)間學(xué)習(xí)完了的基礎(chǔ)自己網(wǎng)上找了一些實(shí)戰(zhàn)項(xiàng)目做了幾個(gè)感覺(jué)項(xiàng)目不是很全面就想做一個(gè)完整的項(xiàng)目來(lái)提升自己的水平以前學(xué)習(xí)的時(shí)候就看過(guò)大神的項(xiàng)目所以自己打算用重寫它后端數(shù)據(jù)還是用實(shí)在沒(méi)有精力擼后端感謝大神該項(xiàng)目是餓了么目前開(kāi)發(fā)了登錄注冊(cè)購(gòu) 前言 前段時(shí)間學(xué)習(xí)完了React的基礎(chǔ),自己網(wǎng)上找了一些實(shí)戰(zhàn)項(xiàng)目,做了幾個(gè)感覺(jué)項(xiàng)目不是很全面,就想做一個(gè)完整的項(xiàng)目來(lái)提升自己的React水平.以前學(xué)習(xí)...
摘要:本文轉(zhuǎn)載至今日頭條技術(shù)博客眾所周知,的單向數(shù)據(jù)流模式導(dǎo)致?tīng)顟B(tài)只能一級(jí)一級(jí)的由父組件傳遞到子組件,在大中型應(yīng)用中較為繁瑣不好管理,通常我們需要使用來(lái)幫助我們進(jìn)行管理,然而隨著的發(fā)布,新成為了新的選擇。 本文轉(zhuǎn)載至:今日頭條技術(shù)博客showImg(https://segmentfault.com/img/bVbiNJO?w=900&h=383);眾所周知,React的單向數(shù)據(jù)流模式導(dǎo)致?tīng)顟B(tài)...
閱讀 3719·2021-11-19 09:56
閱讀 1513·2021-09-22 15:11
閱讀 1189·2019-08-30 15:55
閱讀 3401·2019-08-29 14:02
閱讀 2955·2019-08-29 11:07
閱讀 465·2019-08-28 17:52
閱讀 3195·2019-08-26 13:59
閱讀 461·2019-08-26 13:53