1.Redux概述

當頁面渲染完成后,UI就已經(jīng)出現(xiàn),用戶觸發(fā)了UI上的一些action,action將被送到一個叫Reducer的方法里面去,Reducer將會更新Store,Store中包含state。
使用場景:
組件之間共享信息,例如,用戶登錄之后客戶端會存儲用戶信息(如userid、頭像等),而系統(tǒng)的很多個組件都會用到這些信息,例如收藏、點贊、評論等。因此每個系統(tǒng)都需要一個管理多組間使用的公共信息的功能,這就是Redux的作用。
2.安裝
npm install react-redux redux

網(wǎng)站:
http://redux.js.org/
http://cn.redux.js.org/
3.Redux和React集成
-
第一步:創(chuàng)建更新用戶信息的Action
我們現(xiàn)在主要做的就是初始化城市信息。
首先判斷l(xiāng)ocalStorage中有沒有城市信息,如果有,那么我們就要更新redux中的userinfo中的cityname。
這里的action就是一個改變redux存儲內(nèi)容的行為,這里更新redux中的userinfo中的cityname就是我們的action
//這是redux觸發(fā)數(shù)據(jù)改變的行為,type類型要和reducer中定義的actiontype相同
//第一步:創(chuàng)建更新用戶信息的Action
export function update(data) {
return {
type:'USERINFO_UPDATE',
data
}
}
-
第二步:根據(jù)action定義計算規(guī)則,即reducer
rootReducer.js是所有規(guī)則的入口,可以在這里繼續(xù)添加其他規(guī)則
import {combineReducers} from 'redux'
import userinfo from './userinfo'
//這是redux的第一步定義規(guī)則,這是所有規(guī)則的入口,可以存放多個規(guī)則。
const rootReducer=combineReducers({
userinfo:userinfo
});
export default rootReducer;
userinfo.js是我們定義的一個和用戶相關的規(guī)則,內(nèi)容如下:
這里的action就是第一步創(chuàng)建的action,通過action.type來匹配action和reducer
const initialState ={};
//這是和用戶信息相關的規(guī)則,這里定義了一個更新城市名字的規(guī)則
export default function userinfo(state=initialState,action) {
switch (action.type){
//修改城市名字
case 'UPDATE_CITYNAME':
return action.data;
default:
return state;
}
}
-
第三步:根據(jù)reducer創(chuàng)建store
import {createStore} from 'redux'
import rootReducer from '../reducer/rootReducer'
//redux第二步,創(chuàng)建store
export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState,
// 觸發(fā) redux-devtools
window.devToolsExtension ? window.devToolsExtension() : undefined
);
return store;
}
第四步:監(jiān)聽數(shù)據(jù)變化
在ReactDom.render的index.jsx頁面上,為自己的入口組件添加外層<provider></provider>標簽。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import RouterMap from './routerMap';
import registerServiceWorker from './registerServiceWorker';
import {Provider} from 'react-redux'
import configureStore from './store/configStore'
const store=configureStore();
ReactDOM.render(
<Provider store={store}>
<RouterMap/>
</Provider>
,
document.getElementById('root'));
registerServiceWorker();
第五步:為App組件綁定redux react,根據(jù)路由規(guī)則所有的組件都是App的子組件。所以每次都會先進入App組件
我們在App組件中給Redux初始設置用戶信息,然后在其他組件中獲得Redux中的用戶信息。
- App組件
import React from 'react';
import './App.css';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import * as userInfoActions from './action/userInfoActions'
class App extends React.Component {
constructor() {
super();
this.state = {initDone: false};
}
componentDidMount() {
// 獲取位置信息
let cityName = localStorage.cityName;
if (cityName == null) {
cityName = '北京';
}
//觸發(fā)redux的修改行為
this.props.userInfoActions.update({
cityName: cityName
});
// 更改狀態(tài)
this.setState({
initDone: true
})
}
//首先判斷是否完成初始化
render(){
return (
<div>
{
this.state.initDone ? this.props.children : <div>正在加載</div>
}
</div>
);
}
}
//-------------------redux react 綁定--------------------
//當前組件如需使用redux中的共享數(shù)據(jù),在此設置,就能夠當作屬性來使用
function mapStateToProps(state) {
return {}
}
//觸發(fā)數(shù)據(jù)改變
function mapDispatchToProps(dispatch) {
return {
userInfoActions: bindActionCreators(userInfoActions, dispatch),
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
- 在Home組件中應用這些信息
import React from 'react';
import HomeHeader from '../component/home/homeheader/HomeHeader';
import Category from '../component/home/category/Category';
import Recomment from '../component/home/recommend/Recomment';
import Likelist from '../component/home/likelist/LikeList';
import { connect } from 'react-redux';
class Home extends React.Component{
render(){
return(
<div>
<HomeHeader cityName={this.props.userinfo.cityName}/>
<Category/>
<Recomment/>
<Likelist cityName={this.props.userinfo.cityName}/>
</div>
);
}
}
// -------------------redux react 綁定--------------------
function mapStateToProps(state) {
return {
userinfo: state.userinfo
}
}
//觸發(fā)數(shù)據(jù)變化
function mapDispatchToProps(dispatch) {
return {
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Home)
4.異步react-thunk插件的使用
我們希望在頁面初始化的階段,從后臺根據(jù)用戶的username,返回該用戶所有的收藏商品id,并存儲到redux中。
-
首先定義這個action
//更新收藏列表
export function update(data) {
return {
type:'STORE_UPDATE',
data
}
}
//在App.js中完成頁初始化,從后臺獲取該用戶的所有收藏商品id存儲到redux中
//這里先fetch從后臺獲取json,然后觸發(fā)將json更新到redux的update方法。
export function getInitStore(username) {
return function (dispatch){
console.log('getInitStore執(zhí)行了');
let option={method:'GET'};
fetch(`/api/store/getStore/${username}`,option)
.then(res => res.json())
.then(json => dispatch(update(json)));
};
}
-
之后根據(jù)action定義規(guī)則reducer
const initialState =[];
//收藏創(chuàng)建的規(guī)則
export default function store(state=initialState,action) {
switch (action.type){
//
case 'STORE_UPDATE':
return action.data;
default:
return state;
}
}
在rootReducer中添加規(guī)則store
import {combineReducers} from 'redux'
import userinfo from './userinfo'
import store from './store'
//這是redux的第一步定義規(guī)則,這是所有規(guī)則的入口,可以存放多個規(guī)則。
const rootReducer=combineReducers({
userinfo:userinfo,
store:store
});
export default rootReducer;
-
根據(jù)reducer創(chuàng)建redux的存儲區(qū)
需要安裝redux-thunk插件
npm install redux-thunk --save
import thunkMiddleware from 'redux-thunk';
import {createStore,applyMiddleware,compose} from 'redux'
import rootReducer from '../reducer/rootReducer'
//創(chuàng)建store
export default function configureStore(initialState) {
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducer,initialState,
composeEnhancers(applyMiddleware(thunkMiddleware)
));
return store;
}
- 監(jiān)聽數(shù)據(jù)變化(參考3中第四步)
在ReactDom.render的index.jsx頁面上,為自己的入口組件添加外層<provider></provider>標簽。 - 在app.js中獲得redux的初始值
import React from 'react';
import './App.css';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import * as userInfoActions from './action/userInfoActions'
import * as storeActions from './action/storeActions';
class App extends React.Component {
constructor() {
super();
this.state = {initDone: false};
}
componentDidMount() {
// 獲取位置信息
let cityName = localStorage.cityName;
if (cityName == null) {
cityName = '北京';
}
//觸發(fā)redux的修改行為
this.props.userinfo.cityName=cityName;
this.props.userInfoActions.update(this.props.userinfo);
//獲取用戶名
let username=localStorage.username;
if(username!=null){
//觸發(fā)redux的修改行為
this.props.userinfo.username=username;
this.props.userInfoActions.update(this.props.userinfo);
//觸發(fā)從后臺根據(jù)username獲取個人收藏商品id,存儲在redux中
if(this.props.userinfo.username!=null)
//從后臺獲取收藏信息,觸發(fā)action
this.props.storeActions.getInitStore(this.props.userinfo.username)
}
// 更改狀態(tài)
this.setState({
initDone: true
})
}
//首先判斷是否完成初始化
render(){
return (
<div>
{
this.state.initDone ? this.props.children : <div>正在加載</div>
}
</div>
);
}
}
//-------------------redux react 綁定--------------------
//當前組件如需使用redux中的共享數(shù)據(jù),在此設置,就能夠當作屬性來使用
function mapStateToProps(state) {
return {
userinfo: state.userinfo,
store:state.store
}
}
//觸發(fā)數(shù)據(jù)改變
function mapDispatchToProps(dispatch) {
return {
userInfoActions: bindActionCreators(userInfoActions, dispatch),
storeActions: bindActionCreators(storeActions, dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)






