Redux、React-Redux 簡介
Redux 是 JavaScript 狀態(tài)容器粤咪,提供可預(yù)測化的狀態(tài)管理隔嫡。
盡管 Redux 來自 React 社區(qū)式塌,但它并不依賴于 React劝术。無論有沒有 JavaScript 框架,比如 React呆奕、Angular养晋、Backbone 或 Cycle.js,都可以使用 Redux梁钾。
React-Redux 是Redux 方提供的 React 綁定绳泉。
提供了一個組件和一個API幫助Redux 和 React 進(jìn)行綁定,一個是 React 組件<Provider/> 姆泻,一個是 connect()零酪。
<Provider/> 接受一個 store 作為props,它是 個 Redux 應(yīng)用的頂層組件拇勃,而 connect() 提供了在 個 React 應(yīng)用的任意組件中獲取 store 中數(shù)據(jù)的功能四苇。
Redux基礎(chǔ)
一、Store
Store 就是保存數(shù)據(jù)的地方方咆,你可以把它看成一個容器月腋。整個應(yīng)用只能有一個 Store。
Redux 提供createStore這個函數(shù)瓣赂,用來生成 Store榆骚。
//react-app/index.js
import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './components/App'
import reducer from './reducers'
//用redux創(chuàng)建的store
//createStore函數(shù)接受另一個函數(shù)作為參數(shù),返回新生成的 Store 對象煌集。
const store = createStore(reducer)
// Provider就是把我們用redux創(chuàng)建的store傳遞到內(nèi)部的其他組件妓肢。
//讓內(nèi)部組件可以享有這個store并提供對state的更新。
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
二苫纤、State
Store對象包含所有數(shù)據(jù)碉钠。如果想得到某個時點(diǎn)的數(shù)據(jù)纲缓,就要對 Store 生成快照。這種時點(diǎn)的數(shù)據(jù)集合放钦,就叫做 State色徘。
三、Action
Action 就是 View 發(fā)出的通知操禀,表示 State 應(yīng)該要發(fā)生變化了褂策。
Action 是一個對象。其中的type
屬性是必須的颓屑,表示 Action 的名稱斤寂。其他屬性可以自由設(shè)置,社區(qū)有一個規(guī)范可以參考揪惦。
//react-app/actions/index.js
export const setVisibilityFilter = (filter) => ({
type: 'SET_VISIBILITY_FILTER',
filter
})
四遍搞、Reducer
Store 收到 Action 以后,必須給出一個新的 State器腋,這樣 View 才會發(fā)生變化溪猿。這種 State 的計(jì)算過程就叫做 Reducer。
Reducer 是一個函數(shù)纫塌,它接受 Action 和當(dāng)前 State 作為參數(shù)诊县,返回一個新的 State。
Reducer 函數(shù)最重要的特征是措左,它是一個純函數(shù)依痊。也就是說,只要是同樣的輸入怎披,必定得到同樣的輸出胸嘁。
//react-app/reducers/index.js
import { combineReducers } from 'redux'
import visibilityFilter from './visibilityFilter'
const todoApp = combineReducers({
visibilityFilter
})
export default todoApp
//react-app/reducers/visibilityFilter.js
const visibilityFilter = (state = 'SHOW_ALL', action) => {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}
export default visibilityFilter
React-Redux基礎(chǔ)
一、組件
React-Redux 將所有組件分成兩大類:
1凉逛、展示型組件(presentational component)
2性宏、容器型組件(container component)
展示型組件負(fù)責(zé) UI 的呈現(xiàn),容器型件負(fù)責(zé)管理數(shù)據(jù)和邏輯状飞。
此外React-Redux 提供Provider組件衔沼,負(fù)責(zé)讓容器組件拿到state
1、Provider組件
//react-app/index.js
import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './components/App'
import reducer from './reducers'
//用redux創(chuàng)建的store
//createStore函數(shù)接受另一個函數(shù)作為參數(shù)昔瞧,返回新生成的 Store 對象指蚁。
const store = createStore(reducer)
// Provider就是把我們用redux創(chuàng)建的store傳遞到內(nèi)部的其他組件。
//讓內(nèi)部組件可以享有這個store并提供對state的更新自晰。
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
2凝化、展示型組件特點(diǎn)
1、只負(fù)責(zé) UI 的呈現(xiàn)酬荞,不帶有任何業(yè)務(wù)邏輯
2搓劫、沒有狀態(tài)(即不使用this.state這個變量)
3瞧哟、所有數(shù)據(jù)都由參數(shù)(this.props)提供
4、不使用任何 Redux 的 API
//react-app/components/App.js
import React from 'react'
import Footer from './Footer'
const App = () => (
<div>
<Footer />
</div>
)
export default App
//react-app/components/Footer.js
import React from 'react'
import FilterLink from '../containers/FilterLink'
const Footer = () => (
<p>
Show:
{" "}
<FilterLink filter="SHOW_ALL">
All
</FilterLink>
{", "}
<FilterLink filter="SHOW_ACTIVE">
Active
</FilterLink>
{", "}
<FilterLink filter="SHOW_COMPLETED">
Completed
</FilterLink>
</p>
)
export default Footer
//react-app/components/Link.js
import React from 'react'
import PropTypes from 'prop-types'
const Link = ({ active, children, onClick }) => {
if (active) {
return <span>{children}</span>
}
return (
// eslint-disable-next-line
<a href="#"
onClick={e => {
e.preventDefault()
onClick()
}}
>
{children}
</a>
)
}
Link.propTypes = {
active: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
onClick: PropTypes.func.isRequired
}
export default Link
3枪向、容器型組件特點(diǎn)
1勤揩、負(fù)責(zé)管理數(shù)據(jù)和業(yè)務(wù)邏輯,不負(fù)責(zé) UI 的呈現(xiàn)
2秘蛔、帶有內(nèi)部狀態(tài)
3陨亡、使用 Redux 的 API
//react-app/containers/FilterLink.js
import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'
const mapStateToProps = function(state, ownProps) {
console.log('state : ', state);
console.log('ownProps : ', ownProps);
return {
active: ownProps.filter === state.visibilityFilter
}
}
const mapDispatchToProps = function(dispatch, ownProps){
console.log('mapDispatchToProps')
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter))
}
}
}
const FilterLink = connect(
mapStateToProps,
mapDispatchToProps
)(Link)
export default FilterLink
4、展示型組件和容器型組件對比
二深员、connect()
React-Redux 提供connect方法负蠕,用于從 UI 組件生成容器組件。
connect([mapStateToProps], [mapDipatchToProps], [mergeProps], [options])
connect()一共有四個參數(shù)倦畅,但我這里只說基本的兩個遮糖,mapStateToProps和mapDispatchToProps。
1叠赐、mapStateToProps
mapStateToProps是一個函數(shù)欲账,建立一個從(外部的)state對象到(UI 組件的)props對象的映射關(guān)系。
mapStateToProps執(zhí)行后應(yīng)該返回一個對象芭概,里面的每一個鍵值對就是一個映射赛不。
mapStateToProps會訂閱 Store,每當(dāng)state更新的時候谈山,就會自動執(zhí)行,重新計(jì)算 UI 組件的參數(shù)宏怔,從而觸發(fā) UI 組件的重新渲染奏路。
mapStateToProps的第一個參數(shù)總是state對象,還可以使用第二個參數(shù)臊诊,代表容器組件的props對象鸽粉。
使用ownProps作為參數(shù)后,如果容器組件的參數(shù)發(fā)生變化抓艳,也會引發(fā) UI 組件重新渲染触机。
const mapStateToProps = function(state, ownProps) {
return {
active: ownProps.filter === state.visibilityFilter
}
}
2、mapDispatchToProps
store.dispatch方法的映射玷或。也就是說儡首,它定義了哪些用戶的操作應(yīng)該當(dāng)作 Action,傳給 Store偏友。它可以是一個函數(shù)蔬胯,也可以是一個對象。
2.1位他、mapDispatchToProps是一個函數(shù)
如果mapDispatchToProps是一個函數(shù)氛濒,會得到dispatch和ownProps(容器組件的props對象)兩個參數(shù)产场。
mapDispatchToProps作為函數(shù),應(yīng)該返回一個對象舞竿,該對象的每個鍵值對都是一個映射京景,定義了 UI 組件的參數(shù)怎樣發(fā)出 Action。
const mapDispatchToProps = function(dispatch, ownProps) {
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter))
}
}
}
2.2骗奖、mapDispatchToProps是一個對象
它的每個鍵名也是對應(yīng) UI 組件的同名參數(shù)确徙,鍵值應(yīng)該是一個函數(shù),會被當(dāng)作 Action creator 重归,返回的 Action 會由 Redux 自動發(fā)出米愿。舉例來說,上面的mapDispatchToProps寫成對象就是下面這樣鼻吮。
const mapDispatchToProps = {
onClick: (filter) => {
setVisibilityFilter(filter)
};
}
Redux 的核心 作流程
最后
如果有疑問育苟,請下載示例代碼,也可以歡迎私信或者留言給我椎木。
如果覺得對你有幫助违柏,請點(diǎn)個??,謝謝