10分钟快速上手redux,是真的10分钟

本文简述Redux的基础使用,包括安装、创建store、定义reducer、数据获取与修改,以及组件间的数据共享技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近自己琢磨了一星期,才了解了redux的使用方法。一星期你是在开玩笑吗???
在这里插入图片描述
我们学一样东西,必须知道他有什么用,再了解要怎么运用。那redux是用来干什么的呢?
简而言之,redux是用来传递数据的,实现组件间数据共享。类似于vue里面的vuex。
具体使用方法如下:

  1. 下载redux依赖包
yarn add redux

值得一提的是,redux虽然使用繁琐但可以用于任意项目,vuex只能用于vue项目。

  1. 引入redux并解构出创建仓库的方法
import {createStore} from 'redux'

createStore是一个函数,有三个参数,默认需要传入第一个参数reducer。
createStore在控制台打印出的结果

  1. 创建管理员reducer
//定义一个数据对象defaultState
const defaultState = { num: 1};
//reducer接受两个参数,并返回数据对象
const reducer = (state = defaultState) => {
  return state;
};

这里我们把需要共享的数据对象赋值给reducer的第一个形参,并return出去,其实操作数据的时候,需要用到第二个形参,后面会说到。

  1. 调用createStore方法创建仓库store
//传入必要参数reducer,也就是管理员,才能创建仓库,否则报错
const store = createStore(reducer);

在这里插入图片描述
将store在控制台打印后,可以看到她身上有很多方法。
在这里插入图片描述
其中,getState()是获取仓库数据;dispatch(action)是修改仓库数据;subscribe(listener)是订阅仓库数据
至此,我们就已经搭建好了一个store的数据仓库,可以实现数据传递了。下面我们来玩玩她。

获取仓库数据

import React, { Component } from "react";
import { createStore } from "redux";
const defaultState = { num: 1 };
const reducer = (state=defaultState)=>{
  return state
}
const store = createStore(reducer);
class App extends Component {
  // 从仓库中拿到数据对象
  state = { ...store.getState()};
  render() {
    return (
      <div>仓库的数据 {this.state.num}
      </div>
    );
  }
}

export default App;

修改仓库数据
只有主组件的情况:

import React, { Component } from "react";
import { createStore } from "redux";
const defaultState = { num: 12 };
const reducer = (state = defaultState, action) => {
  // 注意每次获取仓库数据和修改仓库都会触发reducer,不信你可以log一下
  console.log("我被触发了", action);
  // 根据action处理数据
  if (action.type === "hhh") {
    state.num++;
    return state;
  }
  return state;
};
const store = createStore(reducer);
class App extends Component {
  // 从仓库中拿到数据对象
  state = { ...store.getState() };
  // 修改仓库数据
  addNum = () => {
    // 通过dispatch(action)操作仓库
    // 注意这里的action是一个对象,且里面必须有一个属性type,否则会报错
    const action = {
      type: "hhh",
      // 其他自定义属性,根据项目需要
     name:'小明'
    };
    store.dispatch(action);
    // 这个方法调用完后,会自动执行管理员的函数,就是一开始我们设置的reducer,
    // 同时reducer会接收到action对象,这样我们就可以回去reducer写数据修改逻辑了
    // 最后要记得更新视图,否则看不到数据变化
    this.setState({
      num: store.getState().num,
    });
  };
  render() {
    return (
      <div>
        仓库的数据 {this.state.num}{" "}
        <button onClick={this.addNum}>我要修改一下</button>
      </div>
    );
  }
}

export default App;

有子组件的情况,定义了一个类子组件Son

import React, { Component } from "react";
import { createStore } from "redux";
const defaultState = { num: 12 };
const reducer = (state = defaultState, action) => {
  // 注意每次获取仓库数据和修改仓库都会触发reducer,不信你可以log一下
  console.log("我被触发了", action);
  // 根据action处理数据
  if (action.type === "hhh") {
    state.num++;
    return state;
  }
  return state;
};
const store = createStore(reducer);
class Son extends Component {
  state = { ...store.getState() };
  render() {
    return <div>儿子也能获取仓库:{this.state.num}</div>;
  }
}
class App extends Component {
  // 从仓库中拿到数据对象
  state = { ...store.getState() };
  // 修改仓库数据
  addNum = () => {
    // 通过dispatch(action)操作仓库
    // 注意这里的action是一个对象,且里面必须有一个属性type,否则会报错
    const action = {
      type: "hhh",
      // 其他自定义属性,根据项目需要
      // name:'小明'
    };
    store.dispatch(action);
    // 这个方法调用完后,会自动执行管理员的函数,就是一开始我们设置的reducer,
    // 同时reducer会接收到action对象,这样我们就可以回去reducer写数据修改逻辑了
    // 最后要记得更新视图,否则看不到数据变化
    this.setState({
      num: store.getState().num,
    });
  };
  render() {
    return (
      <div>
        仓库的数据 {this.state.num}{" "}
        <button onClick={this.addNum}>我要修改一下</button> <br />
        <Son></Son>
      </div>
    );
  }
}

export default App;

以上代码运行后出现的结果如下
在这里插入图片描述
这是怎么回事呢?在这里插入图片描述
以上的效果不难看出,仓库的数据肯定是改变了,不变的只是子组件Son的视图,要改变视图就必须在子组件写到setState()。那么我们在哪里写呢,这就必须说到仓库的第三个api了。

订阅仓库数据

import React, { Component } from "react";
import { createStore } from "redux";
const defaultState = { num: 12 };
const reducer = (state = defaultState, action) => {
  // 注意每次获取仓库数据和修改仓库都会触发reducer,不信你可以log一下
  console.log("我被触发了", action);
  // 根据action处理数据,处理前要对state进行深拷贝
  if (action.type === "hhh") {
    // let newState = JSON.parse(JSON.stringify(state));
    // newState.num++;
    // return newState;
    state.num++;
    return state;
  }
  return state;
};
const store = createStore(reducer);
class Son extends Component {
  state = { ...store.getState() };
  // 我们想要在子组件挂载完毕后,订阅仓库状态
  componentDidMount() {
    // 要自动更新组件状态,需要执行store的订阅方法subscribe,该方法需要传入一个listener回调函数
    // 该方法会在仓库状态改变时自动执行
    const listener = () => {
      this.setState({
        num: store.getState().num,
      });
    };
    store.subscribe(listener);
  }

  render() {
    return <div>儿子也能获取仓库:{this.state.num}</div>;
  }
}
class App extends Component {
  // 从仓库中拿到数据对象
  state = { ...store.getState() };
  // 修改仓库数据
  addNum = () => {
    // 通过dispatch(action)操作仓库
    // 注意这里的action是一个对象,且里面必须有一个属性type,否则会报错
    const action = {
      type: "hhh",
      // 其他自定义属性,根据项目需要
      // name:'小明'
    };
    store.dispatch(action);
    // 这个方法调用完后,会自动执行管理员的函数,就是一开始我们设置的reducer,
    // 同时reducer会接收到action对象,这样我们就可以回去reducer写数据修改逻辑了
    // 最后要记得更新视图,否则看不到数据变化
    this.setState({
      num: store.getState().num,
    });
  };
  render() {
    return (
      <div>
        仓库的数据 {this.state.num}{" "}
        <button onClick={this.addNum}>我要修改一下</button> <br />
        <Son></Son>
      </div>
    );
  }
}

export default App;

运行结果如下:数据终于同步了
在这里插入图片描述
最后说两点小优化,一点是我们在修改数据的时候可以先深拷贝再return,注释部分是深拷贝。
在这里插入图片描述
第二点是取消订阅,实际项目我们肯定不止一个子组件,当我们切换到其他子组件时,原先的子组件不会自动取消订阅,需要我们在卸载时取消订阅。
在这里插入图片描述
以上就是10分钟上手redux的教程,50行代码不到,超过10分钟你来砍我。如果有不对的地方我先道个歉。

请允许自己写出垃圾,否则你连垃圾都写不出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值