掌握redux

掌握redux

redux其实是JavaScript应用的状态容器, 它保证程序行为一致性且易于测试.

安装

npm install redux --save

流程

  1. 需要一个store来存储数据
  2. store里的reducer初始化state并定义state修改规则
  3. 通过dispatch一个action来提交对数据的修改
  4. action提交到reducer函数里, 根据传入的action的type, 返回新的state
// 新建一个store文件夹,里面添加index.js
import {createStore} from 'redux';
const counterReducer = function(state=1, action) {
	switch(action.type){
		case 'add':
			return state+1;
		case 'minus':
			return state-1;
		default:
			return state;
	}
}
const store = createStore(counterReducer)
export default store
// ----------------------------------------------------
// 需要使用时,在组件中引入store
import store from '../store'
// 如何获得store里的值呢?
{store.getState()}	// => 1
// 想要修改store里的值怎么做呢?
<button onClick={()=>store.dispatch({type:'add'})}>+</button>
<button onClick={()=>store.dispatch({type:'add'})}>+</button>
// 然后需要重新渲染组件才行,这有很多方法, 常用的是下面一种
componentDidMount(){
	store.subscribe(()=>{
		this.forceUpdate();// 强制刷新
	})
}

react-redux

每次都重新调用render和getState太low, 想用更react的方式来写, 需要react-redux

npm install react-redux --save

提供了两个api

  1. Provider为后代组件提供store
  2. connect为组件提供数据和变更方法
// 只需在根app上引入store, 用Provider包裹根组件
import store from './store'
import {Provider} from 'react-redux'
ReactDom.render(
	<Provider store={store}>
		<App />
	</Provider>,
	document.getElementById('root')
)
// 在组件中
import {connect} from 'react-redux'
// 参数一: mapStateToProps = (state)=>{return {num: state}})	// 返回一个对象
// 参数二: 
// mapDispatchToProps = dispatch => {
// 		return {add: ()=>dispatch({type: 'add'})}
// }
@connect(
	state=>({num: state}),
	{
		add:()=>({type: 'add'}),	// actionCreators,
		minus:()=>(type:'minus')
	}
	// 等价于下面这个完整的写法
	dispatch => ({
		add: ()=> dispatch({type:'add'}),
		minus: ()=> dispatch({type:'minus'})
		// dispatch里是一个action对象, action对象其实可以随便写,比如也可以加个
		// {type:'add', color:'red'},只需action.color获取即可
	})
)
class Example extends React.Component {
  render(){
    return(
      <div><h1>{this.props.num}</h1>
        <button onCLick={this.props.add}></button>
        <button onCLick={this.props.minus}></button>
        // 等价于下面,如果像下面这样写就不要actionCreators了
        // <button onCLick={this.props.dispatch({type:'add'})}></button>
      </div>
    )
  }
}
export default Example

异步

其实开发中最常见的问题是异步问题, redux是不支持异步的, 实现异步需要加中间件

Action   =>   Middleware 	=>   Store(Reducer)

npm install redux-thunk redux-logger --save
// 在store中
import {createStore, applyMiddleWare} from 'redux'
import logger from 'redux-logger'
import thunk from 'redux-thunk'

const store = createStore(counterReducers, applyMiddleWare(logger, thunk))
// 在组件中
@connect(
	state=>({num: state}),
	{
		...,
		asyncAdd: ()=>dispatch=>{
			// 在这里执行异步操作
			setTimeout(()=>{
				// 异步结束后,手动执行dispatch
				dispatch({type:'add'})
			},1000)
		}
	}
)

代码优化

一般action不会写到组件里, 写到store里, 在store里建立counter.js

// action
export const add = ()=>({type:'add'});
export const minus = ()=>({type:'minus'});
export const asyncAdd = ()=>dispatch=>{
	// 这里执行异步代码
	setTimeout(()=>{
		// 异步执行完后dispatch
		dispatch({type: 'add'})
	})
}
// reducer也要单独分离出来, 也写在counter.js里
export const counterReducers = function(state=1,action) {
  switch(action.type){
    case 'add':
      return state+1;
    case 'minus':
      return state-1;
    default:
      return state;
  }
}
// store里的index.js
import {combineReducers} from 'redux'
const store = createStore(
	combineReducers({counter: counterReducers}),
	applyMiddleWare(logger, thunk)
)
// 组件中
@connect(
	state => ({num: state.counter}),
	{add, minus, asyncAdd}
)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值