原創(chuàng)文搜囱,最初發(fā)布于 szhshp的第三邊境研究所 , 轉載請注明
Installation
npm install --save react-redux
Some Conceptions
Presentational and container components
Presentational Component
(下稱PC)有這么幾個特性:
- 是個Component
- 這個鬼Component僅僅渲染HTMl
PC
不應該和Redux的Store進行任何交互
Container Components
(下稱CC)有這么幾個特性:
- 給
PC
傳遞Props, 提供數據 - 提供一些action, 如果
PC
需要任何交互操作的話街望,那么就應該調用CC
里面全被你刷屏后天晚上我才要嚴肅的函數, 這個函數一般通過props
傳遞給了PC
CC
應該負責和Redux的各種Dispatcher
Connect with React
今天我確定哪些東西是PC
, 然后確定哪些東西是CC
PC可以先寫起來
CC的話redux推薦使用他們API里面的connect()
函數來自動進行生成
connect
首先看一個例子:
import { connect } from 'react-redux'
?
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
?
export default VisibleTodoList
這是一個CC
, 其中包含了一個PC: TodoList
在傳統(tǒng)React App中,
TodoList
里面僅僅對傳進去的props
進行渲染
connect()函數做的事情是: 將State
已經Dispatcher
的一系列的處理結果轉換成props
并且傳給TodoList
connect
格式:
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])(components)
將components
對應的組件和Redux的store綁定, 并且需要提供幾個重要函數. (見下文)
mapStateToProps
格式:
mapStateToProps(state, [ownProps]): stateProps (Function)
根據當前的
state
以及ownProps
結果返回一個obj, 并且這個obj會被merge到props
里面
-
這個函數會跟
redux
注冊, 類似于綁定, 一旦store
里面的狀態(tài)被更新, 那么這個函數將被調用- 如果不想在這個時候被監(jiān)聽焰扳,那么直接傳一個
null
或者undefined
- 如果不想在這個時候被監(jiān)聽焰扳,那么直接傳一個
- 第二個參數就是對應組件自身的
props
- 另外當傳遞的第二個參數的時候, 如果組件自身的
props
被更新了, 這個函數也會被重新調用, 并且這個比較是一種淺層的比較
- 另外當傳遞的第二個參數的時候, 如果組件自身的
比如: Link是個component, 這個函數的返回值決定當前Link是否應該顯示:
const mapStateToProps = (state, ownProps) => {
return {
active: ownProps.filter === state.visibilityFilter
}
}
const FilterLink = connect(
mapStateToProps,
mapDispatchToProps
)(Link)
mapDispatchToProps
這里面會將不同的
Action的實現
和Dispatch()
動作連接起來
格式:
mapDispatchToProps(dispatch, [ownProps]): dispatchProps (Object or Function)
- 可以傳函數或者是一個對象
- 如果傳一個對象, 那么里面每個Key多一個對應一個
Redux action creator
- 即將實際每個
Action
用dispatch()
包圍起來
- 即將實際每個
- 如果傳的是一個單獨的函數, 那么
dispatch
會被當做第一個參數
- 如果傳一個對象, 那么里面每個Key多一個對應一個
- 如果沒有提供這個值, 那么就會將
dispatch
直接用到這個component里面(也就是不干涉dispatch的細節(jié))
比如下面, 我們給一個Link
的onClick
事件綁定一個dispatch
FilterLink.js:
const setVisibilityFilter = filter => ({
type: 'SET_VISIBILITY_FILTER',
filter
})
const mapDispatchToProps = (dispatch, ownProps) => ({
onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Link)
Presentational Component
隨后就可以在PC
里面獲得傳進去的這兩個參數里面的事件
比如上面放到FilterLink.js
里面的Link.js
可以這么寫:
import React from 'react'
import PropTypes from 'prop-types'
const Link = ({ active, onClick, children }) => (
<button
onClick={onClick}
disabled={active}
>
{children}
</button>
)
Link.propTypes = {
active: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
onClick: PropTypes.func.isRequired
}
export default Link
上方active, onClick
都來自props里面的數據
children
是這個component自身的子dom
Project Structure
推薦的項目架構:
粗體代表是文件夾
- src
- index.html
- actions
- components
- reducers
- containers
- public
- 其他文件(package.json, readme.md等)