IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 2)react-redux抽离redux -> 正文阅读

[JavaScript知识库]2)react-redux抽离redux

为什么用react-redux?

  1. redux与react组件的代码耦合度太高
  2. 编码不够简洁

基本概念

React-Redux将所有组件分成两大类

?UI组件

a.只负责 UI 的呈现,不带有任何业务逻辑

b.通过props接收数据(一般数据和函数)

c.不使用任何 Redux 的 API

d.一般保存在components文件夹下

容器组件

a.负责管理数据和业务逻辑,不负责UI的呈现

b.使用 Redux 的 API

c.一般保存在containers文件夹下

相关API

1.Provider

让所有组件都可以得到state数据

<Provider store={store}>
????<App />
??</Provider>

2.connect()

用于包装?UI 组件生成容器组件

import { connect } from 'react-redux'
??connect(
????mapStateToprops,
????mapDispatchToProps
??)(Counter)

3.mapStateToprops()

将外部的数据(即state对象)转换为UI组件的标签属性
??const mapStateToprops = function (state) {
???return {
?????value: state
???}
??}

4.mapDispatchToProps()

将分发action的函数转换为UI组件的标签属性

简洁语法可以直接指定为actions对象或包含多个action方法的对象

下载包 npm install --save react-redux

优化redux:根据?React-Redux组件分类思想,将app.jsx从上一篇的redux内抽离出来

// app.jsx
import { connect } from "react-redux";
// 引入action内的方法
import { increment, decrement } from "../redux/actions";
// 引入容器组件
import counter from "../components/counter";

export default connect(
  (state) => {
    // state为store内的count值 即0
    console.log(state, "state");
    // 将state状态传给counter组件
    return { count: state };
  },
  // 将increment,decrement方法传给counter
  { increment, decrement }
)(counter);

// counter.js内
// 导入 React 模块
import React, { Component } from "react";

import propTypes from "prop-types";


// 暴露并创建react类
export default class App extends Component {
  static propTypes = {
    count: propTypes.number.isRequired,
    increment: propTypes.func.isRequired,
    decrement: propTypes.func.isRequired,
  };
  addCountFn = () => {
    this.props.increment(this.select.value * 1);
  };
  delCountFn = () => {
    this.props.decrement(this.select.value * 1);
  };
  incrementOddFn = () => {
    const { count } = this.props;
    if (count % 2 === 1) {
      this.props.increment(this.select.value * 1);
    }
  };
  incrementAsyncFn = () => {
    setTimeout(() => {
      this.props.increment(this.select.value * 1);
    }, 1000);
  };
  render() {
    const { count } = this.props;
    return (
      <div>
        <h2>click {count} times</h2>
        <select ref={(select) => (this.select = select)}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        &nbsp;
        <button onClick={this.addCountFn}>+</button>&nbsp;
        <button onClick={this.delCountFn}>-</button>&nbsp;
        <button onClick={this.incrementOddFn}>increment if odd</button>&nbsp;
        <button onClick={this.incrementAsyncFn}>increment async</button>
      </div>
    );
  }
}

// index.js
import React from "react";
import { createRoot } from 'react-dom/client';
import { Provider } from "react-redux";

import store from './redux/store'
import App from "./containers/app";

createRoot(document.getElementById('root')).render(
  <Provider store={store} >
    <App />
  </Provider>
);;

上一篇问题:reducers.js如何暴露多个模块

?// reducers.js
import { COMMENT_ADD, COMMENT_DEL, COMMENT_INIT, INCREMENT, DECREMENT } from "./action-types";
import { combineReducers } from 'redux'
const initCommentData = []

function comments (state = initCommentData, actions) {
  switch (actions.type) {
    // 添加方法
    case COMMENT_ADD:
      return [actions.data, ...state]
    // 删除方法
    case COMMENT_DEL:
      return state.filter((comment, index) => index !== actions.data)
    // 初始化评论
    case COMMENT_INIT:
      return actions.data
    // 默认
    default:
      return state
  }
}

function counter (state = 0, action) {
  switch (action.type) {
    case INCREMENT:
      return state += action.data
    case DECREMENT:
      return state -= action.data
    default:
      return state
  }
}

export default combineReducers(
  {
    comments,
    counter
  }
)

暴露多个模块后,相应的组件 也要做修改

// app.jsx
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";

import Add from "../../components/commentAdd/commentAdd";
import List from "../../components/commentList/commentList";
import { commentAdd, commentDel, commentAsync } from "../../redux/actions";
import "./app.css";

class App extends Component {
  static propTypes = {
    commentList: PropTypes.array.isRequired,
    commentAdd: PropTypes.func.isRequired,
    commentDel: PropTypes.func.isRequired,
    commentAsync: PropTypes.func.isRequired,
  };
  componentDidMount() {
    const { commentAsync } = this.props;
    commentAsync();
  }
  render() {
    const { commentList, commentAdd, commentDel } = this.props;

    return (
      <div id="app">
        <div>
          <header className="site-header jumbotron">
            <div className="container">
              <div className="row">
                <div className="col-xs-12">
                  <h1>请发表对React的评论</h1>
                </div>
              </div>
            </div>
          </header>
          <div className="container">
            <Add commentAdd={commentAdd} />
            <List commentList={commentList} commentDel={commentDel} />
          </div>
        </div>
      </div>
    );
  }
}


export default connect((state) => 
// 此处为reducers修改后调整
({ commentList: state.comments }), 
{
  commentAdd,
  commentDel,
  commentAsync
}
)(App);
// store.js 存储 状态变量

import { configureStore } from '@reduxjs/toolkit'

import reducers from './reducers'

// 根据comments函数创建store对象

const store = configureStore({ reducer: reducers })
console.log(store, 'store');
export default store
 


?

redux如何处理异步操作???

redux-thunk处理异步操作_FF_XM的博客-CSDN博客

redux基本概念

redux初体验(问题记录)_FF_XM的博客-CSDN博客

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:05:12  更:2022-09-13 11:08:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:05:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码