实操redux

一、引子

今天利用一个小案例完成对redux的知识回顾。首先看效果(完整代码见文末):

在这里插入图片描述
完成功能:
1.利用redux完成加1、减1、加任意值、异步加1
2.实现两个组件间的数据共享
3.一些代码优化

二、redux版

首先建立src文件夹如下结构(示例):
在这里插入图片描述
创建store:

//store/index.js
// 1.引入createStore
//applyMiddleware在异步操作时使用
import {createStore,applyMiddleware} from 'redux';
//支持异步操作action
import thunk from 'redux-thunk';
//2.引入汇总后的ruducer
import reducer from './ruducer/index';
//3.创建store并暴露
//applyMiddleware(thunk)异步操作时使用,没有异步省略
export default createStore(reducer,applyMiddleware(thunk))

创建reducer:

//reducer/index.js
//引入combineReducers来合并reducer
import {combineReducers} from 'redux';
import count from './count';
import user from './user';

//合并reducer,并暴露,combineReducers传入一个对象key:value的形式,
export default combineReducers({
  //自定义名称:reducer模块,因为名称一样,基于es6省略,下同
  count,
  user
})

首先实现count组件的功能,user组件同理:

//reducer/count.js
//使用 * as引入常量
import * as at from '../constant';

//自定义默认值
const initState = {
  num:18
}
//定义reducer
let count = (state=initState,action)=>{
  switch (action.type) {
    case at.INCRE:
      return {...state,num:state.num + action.num}
    case at.DECRE:
      return {...state,num:state.num - action.num}
    default:
      return state;
  }
}
export default count

创建常量文件:

//countant.js
//暴露使用到的常量,通常一个文件
export const INCRE = 'incre'
export const DECRE = 'decre'
export const INCREASYNC = 'increAsync'

创建count的action动作文件:

//action/count.js
import * as at from '../constant';
//分离action动作,并暴露
export const increAction = (val)=>{
  return { type: at.INCRE, num: val * 1 }
}

export const decreAction = ()=>{
  return { type: at.DECRE, num: 1 }
}
//异步操作时在action里操作,返回一个回调函数,同时传递dispatch,
//异步操作也是调用同步操作方法,直接在action里调用,不经过组件自身
export const increAsyncAction = (val,time)=>{
  return (dispatch)=>{
    setTimeout(() => {
      dispatch(increAction(val))
    }, time);
  }
}

读取操作数据:

//components/count.js
import React, { Component } from 'react'
import store from '../store';
import {
  increAction,
  decreAction,
  increAsyncAction,
} from '../store/action/count';

export default class count extends Component {
  input = React.createRef();
  incre = (val) => {
    store.dispatch(increAction(val));
  };
  decre = () => {
    store.dispatch(decreAction());
  };
  increAsync =(val,time)=>{
    store.dispatch(increAsyncAction(val,time));
  }
  render() {
    return (
      <div>
        {store.getState().count.num}
        <button onClick={()=>{this.incre("1")}}>+1</button>
        <button onClick={this.decre}>-1</button>
        <input type="text" ref={this.input} />
        <button onClick={()=>{this.incre(this.input.current.value)}}>点击加数值</button>
        <button onClick={()=>{this.increAsync("1","500")}}>异步加</button>
      </div>
    );
  }
}

通过subscribe监听数据变化:

//index.js最后加入这么一句
store.subscribe(()=>{
  ReactDOM.render(<App />, document.getElementById("root"))
})

这样count组件的功能就可以实现了。

三、react-redux版

在redux的基础上实现redux数据与ui组件的分离.

首先使用Provider包裹App根组件,传递store,使得所有组件都能使用store。

import { Provider } from 'react-redux'


ReactDOM.render(
  //Provider为所有组件提供store
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
)

在组件里引用react-redux里的connect方法,connect接收两个参数mapStateToProps,mapDispatchToProps对象,将组件在最后暴露:

//mapStateToProps:映射状态,返回值是一个对象
//-mapDispatchToProps:映射操作状态的方法,返回值是一个对象
export default connect(
  (state) => ({
    count:state.count,
    user:state.user
  }),
  // dispatch =>({
  //   incre:(val)=>dispatch(increAction(val)),
  //   decre:()=>dispatch(decreAction()),
  //   increAsync:(val,time)=>dispatch(increAsyncAction(val,time))
  // })
  //mapDispatchToProps对象的简写
  {
    incre: increAction,
    decre: decreAction,
    increAsync: increAsyncAction,
  }
)(count);

在组件中读取数据时:

<h2>这是Count组件:下方的组件列表长度为:{this.props.user.length}</h2>
        {this.props.count.num}

在组件中操作状态的方法:


  incre = (val) => {
    // store.dispatch(increAction(val));
    this.props.incre(val)
  };
  decre = () => {
    // store.dispatch(decreAction());
    this.props.decre()
  };
  increAsync =(val,time)=>{
    // store.dispatch(increAsyncAction(val,time));
    this.props.increAsync(val,time)
  }

这样就完成了对count组件的react-redux化,user组件相同

四、两个组件之间数据共享

  • 1.使用combinReducers合并对象,定义好模块名与模块对应 ;
//引入combineReducers来合并reducer
import {combineReducers} from 'redux';
import count from './count';
import user from './user';

//合并reducer,并暴露,combineReducers传入一个对象key:value的形式,
export default combineReducers({
  //自定义名称:reducer模块,因为名称一样,基于es6省略,下同
  count,
  user
})
  • 2.在组件里mapStateToProps取值,如user组件取count的组件:

export default connect(
  state=>({
    user:state.user,
    count:state.count
  }),
  {
    addUser
  }
)(user)

在页面上读取:

<h2>这是User组件:上方组件总数为:{this.props.count.num}</h2>

五、可优化的地方

  • 1.使用react-redux后无需监听数据变化来进行渲染,connect方法会自动进行 页面渲染;
  • 2.mapDispatchToprops参数对象会自动进行dispatch分发动作,因此它也可以是一个对象,可以简写成{incre: increAction,…},可以设置名称相同,那么只需写一个incre即可。
  • 3.箭头函数一个参数可以省略括号,return 是一个对象时可以省略return关键字,同时使用一个小括号包裹。

六、完整代码

https://gitee.com/maya1024/react-exercise

注:src里的是react-redux版,需要运行redux版时,将使用redux文件夹修改为src,原src另外修改个名字即可

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值