react-redux

不用react-redux

我们现在要实现一个这样的功能:

有两个组件分别为Home 、About,数据都来源于redux,两个组件中都有加减功能,都会影响redux里面的counter数据
在这里插入图片描述

先来看如果我们不用react-redux要实现一个这样的功能要怎么来写?
首先我们定义action,我们肯定要去定义一些actionCreators来创造action对象,而且type事件既要被reducers来捕获,而且也要在actionCreators来定义action也需要,因此定义四个type事件(因为有4个功能):

export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
export const ADD_NUMBER = 'ADD_NUMBER'
export const SUB_NUMBER = 'SUB_NUMBER'

接下来定义actionCreators

import {
    ADD_NUMBER,
    SUB_NUMBER,
    INCREMENT,
    DECREMENT,
} from './constant'

export const addAction = num => ({
    type: ADD_NUMBER,
    num,
})
export const subAction = num => ({
    type: SUB_NUMBER,
    num
})
export const incAction = () => ({
    type: INCREMENT
})
export const decAction = () => ({
    type: DECREMENT
})

接下来我们肯定要根据不同的type事件,来定义不同的reducers来分别做对应的处理,分别用switch-case来做判断:

import {
    ADD_NUMBER,
    SUB_NUMBER,
    INCREMENT,
    DECREMENT,
} from '../actionCreators/constant'

const defaultState = {
    counter: 0
}

function reducer(state = defaultState, action) {
    switch(action.type) {
        case ADD_NUMBER:
            return {...state, counter: state.counter + action.num}
        case SUB_NUMBER:
            return {...state, counter: state.counter - action.num}
        case INCREMENT:
            return {...state, counter: state.counter + 1}
        case DECREMENT:
            return {...state, counter: state.counter - 1}
        default:
            return state;
    }
}

export default reducer

最后我们来写store的代码,我们用redux的createStore来创建store对象,并把前面的reducers丢进去:

import reducer from "./reducer";
import {createStore} from 'redux'

const store = createStore(reducer)

export default store;

然后我们需要定义home和about组件的代码,逻辑就是在render函数中return回jsx代码,引入store对象用来dispatch action,并且监听redux的变化进而做对应的处理,(这里应该是可以做性能的优化的,因为只要redux有变化,那么肯定会触发store.subscribe()执行里面的callback,然后执行this.setState(),然后重新调用render函数,但是有时候redux改变了但是组件里需要的数据并没有发生改变,那就没必要重新render,connect函数其实做了这方面的优化,做了浅层比较)。
这个事情其实可以做一个测试:
在这里插入图片描述我们about组件并没有依赖redux的数据,但是做了监听,发现即使没有依赖但是redux发生了变化仍然会重新渲染about组件。

之后返回unSubscribe函数,在componentWillUnmount()中去调用,卸载监听。
在页面发生点击事件的时候,调用store.dispatch()来创建action对象进而去修改redux中的state:
Home:

import React from 'react'

import store from '../store'
import {
  addAction,
  subAction,
  incAction,
  decAction,
} from '../actionCreators';

export default class Home extends React.Component {
  state = {
    counter: store.getState().counter
  }

  addNumber = () => {
    store.dispatch(incAction())
  }
  decNumber = () => {
    store.dispatch(decAction())
  }
  addNumber5 = () => {
    store.dispatch(addAction(5))
  }
  decNumber5 = () => {
    store.dispatch(subAction(5))
  }
  componentDidMount() {
    this.unSubscribe = store.subscribe(() => {
      console.log(store.getState().counter)
      this.setState({
        counter: store.getState().counter
      })
    })
  }
  componentWillUnmount() {
    this.unSubscribe();
  }

  render() {
    return (
      <div>
        <h2>总数: {this.state.counter}</h2>
        <button onClick={this.addNumber}>+1</button>
        <button onClick={this.decNumber}>-1</button>
        <button onClick={this.addNumber5}>+5</button>
        <button onClick={this.decNumber5}>-5</button>
      </div>
    );
  }
  
}

About

import React from 'react'

import store from '../store'
import {
  addAction,
  subAction,
  incAction,
  decAction,
} from '../actionCreators';


export default class About extends React.Component {
  state = {
    counter: store.getState().counter
  }

  addNumber = () => {
    store.dispatch(incAction())
  }
  decNumber = () => {
    store.dispatch(decAction())
  }
  addNumber5 = () => {
    store.dispatch(addAction(5))
  }
  decNumber5 = () => {
    store.dispatch(subAction(5))
  }
  componentDidMount() {
    this.unSubscribe = store.subscribe(() => {
      console.log(store.getState().counter)
      this.setState({
        counter: store.getState().counter
      })
    })
  }
  componentWillUnmount() {
    this.unSubscribe();
  }

  render() {
    return (
      <div>
        <h2>总数: {this.state.counter}</h2>
        <button onClick={this.addNumber}>+1</button>
        <button onClick={this.decNumber}>-1</button>
        <button onClick={this.addNumber5}>+5</button>
        <button onClick={this.decNumber5}>-5</button>
      </div>
    );
  }
  
}

使用react-redux

通过上面的代码我们会发现几个问题:

  • home和about重复代码太多
  • 并没有做性能优化,redux发生改变了就会重新调用callback进而重新执行render函数
  • 页面组件和redux交互并没有做很好的分离,当页面发生点击事件以后需要向redux发出dispatch,然后重新setState,通过react-redux我们可以只关心页面组件里的东西。
    用react-redux优化以后:
import React, {Component} from 'react'
import store from '../store'
import {
    addAction,
    decAction,
} from '../actionCreators'
import {connect} from 'react-redux'

function Home(props) {
    return (
        <div>
            <h2>总数:{props.counter}</h2>
            <button onClick={props.add5}>+5</button>
            <button onClick={props.sub5}>-5</button>
        </div>
    )
}

const mapStateToProps = state => ({
    counter: state.counter
})
const mapDispatchToProps = dispatch => ({
    add5() {
        dispatch(addAction(5))
    },
    sub5() {
        dispatch(decAction(5))
    }
})

export default connect(mapStateToProps, mapDispatchToProps)(Home)

并用Provider将App组件包裹一层

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React-Redux是一个结合了ReactRedux的库,它使得在React应用中集成状态管理变得更加容易。Redux是一个单一来源的状态管理库,而React-Redux提供了一组工具来帮助你将Redux的状态管理与React组件结合起来。 安装React-Redux的步骤通常是这样的: 1. 首先,确保你已经安装了Node.js和npm(Node包管理器)。 2. 在你的项目目录中,打开终端或命令提示符。 3. 使用npm或yarn来安装`react-redux`和`redux`库。如果你还没有安装`redux`,可以先安装: ```bash npm install redux ``` 或者使用yarn: ```bash yarn add redux ``` 4. 安装`react-redux`: ```bash npm install react-redux ``` 或者: ```bash yarn add react-redux ``` 5. 引入到你的项目中。通常会创建一个store来保存全局状态,以及将store连接到React组件上: ```javascript // 在index.js或App.js中 import { createStore } from 'redux'; import rootReducer from './reducers'; // 根 reducer,合并所有模块的reducer const store = createStore(rootReducer); // 如果你在使用react-redux,还需要引入Provider组件: import { Provider } from 'react-redux'; import App from './App'; // 你的React应用组件 function Root() { return ( <Provider store={store}> <App /> </Provider> ); } ReactDOM.render(<Root />, document.getElementById('root')); ``` 6. 在React组件中,使用`connect`函数从store中提取数据并处理dispatch动作: ```javascript import { useSelector, useDispatch } from 'react-redux'; function MyComponent() { const myState = useSelector(state => state.mySlice); // 选择store中的状态 const dispatch = useDispatch(); // 获取dispatch方法 // 在组件内部使用state和dispatch // ... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值