在React项目中使用Redux实现计数器功能

Redux 和 React 之间没有关系。Redux 支持 ReactAngularEmber、jQuery 甚至纯 JavaScript。尽管如此,Redux 还是和 React 和 Deku 这类库搭配起来用最好,因为这类库允许你以 state 函数的形式来描述界面,Redux 通过 action 的形式来发起 state 变化。

下面我们来看一个使用 react-redux 完成计数器的案例:

最终实现的效果:点击左边的加号按钮,中间的数字加2(可以自定义参数);点击右边的减号按钮,中间的数字减1;
在React项目中使用Redux实现计数器功能
目录结构

├── index.jsx	//入口文件
├── Count.jsx	//显示页面内容的组件
├── Button.jsx	//按钮组件
├── store.js	//创建一个store,用来集中管理state dispatch action
├── reducer.js	//业务逻辑层,对数据进行操作,并返回新的state
├── connect.js	//将redux和展示组件做关联,将redux中的属性和方法挂载到组件里

安装依赖:在终端中执行下面的命令,安装 redux 和 react-redux
yarn add redux react-redux -S

store.js文件

  • 用来创建一个 store,集中管理state dispatch action,参数是 reducer。
/* store.js */
import {createStore} from 'redux'
import reducer from './reducer'

//创建store
const store=createStore(reducer)

export default store;

reducer.js文件

  • reducer 是一个纯函数,它接收两个参数 state 和 action;
  • 当处理数据时,先把原来的数据拿过来,如果没有数据,会读取初始值
  • reducer 是业务逻辑层,代码根据业务需求来写,它的作用是根据 action 传过来的内容,对数据做操作
  • reducer 最终返回一个新的state,当 state 被更改后,store.subscribe 方法里的回调函数就会执行,会通知 view 去重新获取 state,做视图的更新;
/* reducer.js */
const defaultState={count:1}
const reducer=(state=defaultState,action)=>{
    switch (action.type){
        case "inc":
            return{ count:state.count+action.num }
        case "dec":
            return{ count:state.count-1 }
        default:
            return state;
    }
}
export default reducer;

connect.js文件

  • 帮我们把redux展示组件关联,将 store 里的属性和方法挂载到组件里;
  • connect 就是一个高阶函数,把组件作为参数传进去,组件中就能读到store中的数据;
  • connect 的语法格式为: connect(mapStateToProps?, mapDispatchToProps?)(component)
    • 将第一个参数中返回的属性转化为展示组件props上的属性;
    • 将第二个参数中返回的方法转化为展示组件props上的方法;
    • 如果只想获取到方法,在第一个参数传null;
/* connect.js */
import {connect} from 'react-redux'

const mapState=(state)=>{
    return{ count:state.count }
}

const mapDispatch=(dispatch)=>{
    return{
        increm:(data)=>{ dispatch({type:"inc",num:2}) },
        decrem:()=>{ dispatch({type:"dec"}) }
    }
}

export default connect(mapState,mapDispatch)

Count.jsx

  • 使用 connect 对当前组件做一个增强,Count 组件里就可以通过 this.props 读取到 store 中的数据;
/* Count.jsx */
import React, { Component } from 'react'
import Button from './Button'
import connect from './connect'

class Count extends Component {
    render() {
        return (
            <div>
                <Button type="inc">+</Button>
                <span>{this.props.count}</span>
                <Button type="dec">-</Button>
            </div>
        )
    }
}

export default connect(Count)

Button.jsx

  • 使用 connect 对当前组件做一个增强,Button 组件里通过 this.props 调用 connect 中的方法;
  • connect 中调用 store.dispatch 方法将 action 发送到 reducer 中;
  • reducer 接收到 action,对数据进行处理后,返回新的 state;
  • 当 state 被更新的时候,store.subscribe 方法会执行,通知 view 去重新获取 state;
  • 获取到新的 state 后,会触发 render() 重新渲染页面;
/* Button.jsx */
import React, { Component } from 'react'
import connect from './connect'

class Button extends Component {
    clickHandle=()=>{
        let {type,increm,decrem} =this.props;
        if(type==="inc") increm(2)
        else decrem()
    }
    render() {
        return (
            <button onClick={this.clickHandle}>
                {this.props.children}
            </button>
        )
    }
}

export default connect(Button)

index.js

  • 在父组件最外面包裹<Provider>,并提供 store 属性,则在后代组件中都可以通过 connect 对组件做增强,读到 store 里的属性和方法;
/* index.js */
import React from 'react'
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux'
import store from './store'
import Count from './Count'

ReactDOM.render(
  <Provider store={store}>
    <Count/>
  </Provider>,
  document.getElementById('root')
);

总结:

react-redux 中两个核心的api:

  • Provider: 提供store,根据单一store原则 ,一般只会出现在整个应用程序的最顶层。
  • connect: 用于连接展示组件和 store。

react-redux 开发思想:

Redux 的 React 绑定库是基于容器组件和展示组件相分离的开发思想。

展示组件容器组件
作用描述如何展现(骨架、样式)描述如何运行(数据获取、状态更新)
直接使用 Redux
数据来源props监听 Redux state
数据修改从 props 调用回调函数向 Redux 派发 actions
调用方式手动通常由 React Redux 生成

大部分的组件都应该是展示型的,但一般需要少数的几个容器组件把它们和 Redux store 连接起来。技术上讲你可以直接使用 store.subscribe() 来编写容器组件。但不建议这么做的原因是无法使用 React Redux 带来的性能优化。也因此,不要手写容器组件,而使用 React Redux 的 connect() 方法来生成。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值