1、安装
cnpm install redux --save
2、创建action-type.js文件
用途:
用来放置action的type属性的常量
export const XX='XX'
3、创建actions.js文件
用途:
用来创建action对象
action中存储type类型和数据,会根据type来进行何种操作,数据来进行状态更新
(1)引入action-type.js
import { xx,xx,.. } from "./action-type";
(2)通过函数返回action对象
export const xx=(数据参数)=>({type:XX,data:参数});
其中:除了type属性外其他可自定义
4、创建reducers.js文件
用途:
是数据的保存地方和返回数据的地方
其中的函数是用来操作状态的函数
会根据action对象,来进行对应的操作
state和action为必要参数
state的值会自动更新成返回值
state不能修改(即不能改动state,.splice()这样的方法不能使用)
数组添加:[...state,...]
数组删除:state.filter((item,index)=>{... return true})
(1)引入action-type.js
import { xx,xx,.. } from "./action-type";
(2)创建并暴露函数
export function xxx(state=0,action)
{
switch(action.type)
{
case xx:
return 操作
case xx:
return 操作
default: //初始状态
return state; 可在形参中设定初始值
}
}
5、创建store.js文件
用途:
根据reducer来生成store仓库,是调用的入口
(1)引入创建仓库方法
import {createStore} from 'redux';
(2)引入reducer内的方法
import {xx} from './reducers'
(3)创建store并导出
const store=createStore(xx)
export default store;
6、注册仓库,并根据状态变化重新渲染应用(可使用react-redux简化)
(1)在index.js中引入store
import store from './redux/store'
(2)将store注册进整个应用,即第一次初始化状态
ReactDOM.render(
<App store={store} />
,
document.getElementById('root')
);
(3)数据改变,渲染应用,再第二步后面添加
订阅监听实现状态改变,渲染页面
store.subscribe(function(){
ReactDOM.render(
<App store={store} />
,
document.getElementById('root')
);
})
7、调用方法管理数据(可使用react-redux简化)
(1)在页面中引入需要的action对象,可以使用{}来按需引入
import * as actions from './redux/actions'
(2)调用reducer内的方法来改变状态
1、获取状态:this.props.store.getState();
2、改变状态:this.props.store.dispatch(actionsxx(传递参数))
代码示例:
action-type.js:
export const INCREMENT='INCREMENT'
export const DECREMENT='DECREMENT'
actions.js:
/*
创建action的函数
*/
import { INCREMENT,DECREMENT } from "./action-type";
export const increment=(num)=>({type:INCREMENT,data:num})
export const decrement=(num)=>({type:DECREMENT,data:num})
reducers.js:
import {INCREMENT,DECREMENT} from './action-type'
export function counter(state=0,action)
{
console.log('counter()',state,action);
switch(action.type)
{
case INCREMENT:
return state+action.data
case DECREMENT:
return state-action.data
default: //初始状态
return state
}
}
store.js:
import {createStore} from 'redux';
import {counter} from './reducers'
const store=createStore(counter)
console.log(store);
export default store;
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {BrowserRouter} from 'react-router-dom'
import store from './redux/store'
ReactDOM.render(
<BrowserRouter>
<App store={store} />
</BrowserRouter>
,
document.getElementById('root')
);
//订阅监听实现状态改变,渲染页面
store.subscribe(function(){
ReactDOM.render(
<BrowserRouter>
<App store={store} />
</BrowserRouter>
,
document.getElementById('root')
);
})
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
App.js:
import React from 'react';
import './App.css';
import * as actions from './redux/actions'
class App extends React.Component{
increment = () => {
const num = this.refs.numSelect.value*1
this.props.store.dispatch(actions.increment(num));
}
decrement = () => {
const num = this.refs.numSelect.value*1
this.props.store.dispatch(actions.decrement(num))
}
incrementIfOdd = () => {
const num = this.refs.numSelect.value*1
const count=this.props.store.getState();
if(count%2==1) {
this.props.store.dispatch(actions.increment(num))
}
}
incrementAsync = () => {
setTimeout(() => {
const num = this.refs.numSelect.value*1
this.props.store.dispatch(actions.increment(num))
}, 1000)
}
render () {
const count = this.props.store.getState()
return (
<div>
<p>
click {count} times {' '}
</p>
<select ref="numSelect">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>{' '}
<button onClick={this.increment}>+</button>{' '}
<button onClick={this.decrement}>-</button>{' '}
<button onClick={this.incrementIfOdd}>increment if odd</button>{' '}
<button onClick={this.incrementAsync}>increment async</button>
</div>
)
}
}
export default App;