当前位置: 首页 > news >正文

企业英语网站/网络推广发帖网站

企业英语网站,网络推广发帖网站,做公司网站别人能看到吗,wordpress视频模板下载来源| coderwhy一. react结合redux1.1. redux融入react代码目前redux在react中使用是最大的,所以我们需要将之前编写的redux代码,融入到react当中去。这里我创建了两个组件:Home组件:其中会展示当前的counter值,并且有…

来源| coderwhy

一. react结合redux

1.1. redux融入react代码

目前redux在react中使用是最大的,所以我们需要将之前编写的redux代码,融入到react当中去。

这里我创建了两个组件:

  • Home组件:其中会展示当前的counter值,并且有一个+1和+5的按钮;
  • Profile组件:其中会展示当前的counter值,并且有一个-1和-5的按钮;
3ca207add2501d5e314c45e4663bec65.png

界面展示效果

home.js代码实现:

import React, { PureComponent } from 'react';import store from '../store';import {  addAction} from '../store/actionCreators';export default class Home extends PureComponent {  constructor(props) {    super(props);    this.state = {      counter: store.getState().counter    }  }  componentDidMount() {    store.subscribe(() => {      this.setState({        counter: store.getState().counter      })    })  }  render() {    return (      
        

Home

        

当前计数: {this.state.counter}

         this.increment()}>+1         this.addCounter()}>+5      
    )  }  increment() {    store.dispatch(addAction(1));  }  addCounter() {    store.dispatch(addAction(5));  }}

Profile.js代码实现:

import React, { PureComponent } from 'react';import store from '../store';import {  subAction} from '../store/actionCreators';export default class Profile extends PureComponent {  constructor(props) {    super(props);    this.state = {      counter: store.getState().counter    }  }  componentDidMount() {    store.subscribe(() => {      this.setState({        counter: store.getState().counter      })    })  }  render() {    return (      
                

Profile

        
          

当前计数: {this.state.counter}

           this.decrement()}>-1           this.subCounter()}>-5        
      
    )  }  decrement() {    store.dispatch(subAction(1));  }  subCounter() {    store.dispatch(subAction(5));  }}

上面的代码其实非常简单,核心代码主要是两个:

  • 在 componentDidMount 中定义数据的变化,当数据发生变化时重新设置 counter;
  • 在发生点击事件时,调用store的dispatch来派发对应的action;

1.2. 自定义connect函数

上面的代码是否可以实现react组件和redux结合起来呢?

  • 当然是可以的,但是我们会发现每个使用的地方其实会有一些重复的代码:
  • 比如监听store数据改变的代码,都需要在 componentDidMount中完成;
  • 比如派发事件,我们都需要去先拿到 store, 在调用其 dispatch 等;

能否将这些公共的内容提取出来呢?

我们来定义一个connect函数:

  • 这个connect函数本身接受两个参数:
    • 参数一:里面存放 component 希望使用到的 State 属性;
    • 参数二:里面存放 component 希望使用到的 dispatch动作;
  • 这个connect函数有一个返回值,是一个高阶组件:
    • 在constructor中的state中保存一下我们需要获取的状态;
    • 在componentDidMount中订阅store中数据的变化,并且执行 setState操作;
    • 在componentWillUnmount中需要取消订阅;
    • 在render函数中返回传入的WrappedComponent,并且将所有的状态映射到其props中;
    • 这个高阶组件接受一个组件作为参数,返回一个class组件;
    • 在这个class组件中,我们进行如下操作:
import React, { PureComponent } from "react";import store from '../store';export default function connect(mapStateToProps, mapDispatchToProps) {  return function handleMapCpn(WrappedComponent) {    return class extends PureComponent {      constructor(props) {        super(props);        this.state = {          storeState: mapStateToProps(store.getState())        }      }      componentDidMount() {        this.unsubscribe = store.subscribe(() => {          this.setState({            storeState: mapStateToProps(store.getState())          })        })      }      componentWillUnmount() {        this.unsubscribe();      }      render() {        return       }    }  }}

在home和props文件中,我们按照自己需要的state、dispatch来进行映射:

比如home.js中进行如下修改:

  • mapStateToProps:用于将state映射到一个对象中,对象中包含我们需要的属性;
  • mapDispatchToProps:用于将dispatch映射到对象中,对象中包含在组件中可能操作的函数;
    • 当调用该函数时,本质上其实是调用dispatch(对应的Action);
const mapStateToProps = state => {  return {    counter: state.counter  }}const mapDispatchToProps = dispatch => {  return {    addNumber: function(number) {      dispatch(addAction(number));    }  }}export default connect(mapStateToProps, mapDispatchToProps)(Home);

在Profile中也是类似的操作。

有了connect函数,我们之后只需要关心从state和dispatch中映射自己需要的状态和行为即可;

1.3. store的context处理

但是上面的connect函数有一个很大的缺陷:依赖导入的store

  • 如果我们将其封装成一个独立的库,需要依赖用于创建的store,我们应该如何去获取呢?
  • 难道让用户来修改我们的源码吗?不太现实;

正确的做法是我们提供一个Provider,Provider来自于我们创建的Context,让用户将store传入到value中即可;

创建一个context.js文件:

import { createContext } from 'react';export const StoreContext = createContext();

修改connect函数中class组件部分的代码:

  • 注意下面我们将class组件的名称明确的定义出来,并且给它的contextType进行了赋值;
  • 在组件内部用到store的地方,统一使用this.context代替(注意:constructor中直接使用第二个参数即可)
import React, { PureComponent } from "react";import { StoreContext } from './context';export default function connect(mapStateToProps, mapDispatchToProps) {  return function handleMapCpn(WrappedComponent) {    class ConnectCpn extends PureComponent {      constructor(props, context) {        super(props);        this.state = {          storeState: mapStateToProps(context.getState())        }      }      componentDidMount() {        this.unsubscribe = this.context.subscribe(() => {          this.setState({            storeState: mapStateToProps(this.context.getState())          })        })      }      componentWillUnmount() {        this.unsubscribe();      }      render() {        return       }    }    ConnectCpn.contextType = StoreContext;    return ConnectCpn;  }}

在入口的index.js中,使用Provider并且提供store即可:

import { StoreContext } from './utils/context';import store from './store';ReactDOM.render(        ,  document.getElementById('root'));

测试代码,依然可以正常运行。

二. react-redux使用

2.1. react-redux的使用

开始之前需要强调一下,redux和react没有直接的关系,你完全可以在React, Angular, Ember, jQuery, or vanilla JavaScript中使用Redux。

尽管这样说,redux依然是和React或者Deku的库结合的更好,因为他们是通过state函数来描述界面的状态,Redux可以发射状态的更新,让他们作出响应。

虽然我们之前已经实现了connect、Provider这些帮助我们完成连接redux、react的辅助工具,但是实际上redux官方帮助我们提供了 react-redux 的库,可以直接在项目中使用,并且实现的逻辑会更加的严谨和高效。

安装react-redux:

yarn add react-redux

使用connect函数:

  • 将之前使用的connect函数,换成react-redux的connect函数;
import React, { PureComponent } from 'react';import { connect } from "react-redux";// import connect from '../utils/connect2';export default connect(mapStateToProps, mapDispatchToProps)(Home);

使用Provider:

  • 将之前自己创建的Context的Provider,换成react-redux的Provider组件:
  • 注意:这里传入的是store属性,而不是value属性(待会儿可以在源码中查看);
import { Provider } from 'react-redux';import store from './store';ReactDOM.render(        ,  document.getElementById('root'));

2.2. react-redux的源码

这里我简单带着大家看一下react-redux的源码:

  • 但是第一因为这个教程不是讲源码为主的教程(穿插讲解部分源码),所以源码只会阅读核心的部分;
  • 另外我经常会说,整个社区在hooks出现后大量的库转向了hooks,所以在源码中会出现大量的hooks代码;
  • 因为目前还没有讲解hooks相关的API,所以某些hooks的作用在这里也不方便解释(可以学习完hooks之后再详细阅读);

首先,我们简单看一下Provider的源码:

  • 使用了一个useMemo来返回一个contextValue的对象;
    • 这里使用useMemo的原因是为了进行性能的优化;
    • 在依赖的store不改变的情况下,不会进行重新计算,返回一个新的对象;
  • 在下面的Context的Provider中就会将其赋值给value属性;
02e2eaa80df5f65b8558d41435212e55.png

image-20200713171101825

ReactReduxContext来自另外一个文件:

f029c9d901a982d84e904f5d127aec1c.png

Context对象的创建

connect函数的依赖比较复杂:

调用createConnect来返回一个connect函数:

d78a7d404e787b5c9b3228400b5ef66d.png

image-20200713171920708

createConnect函数的调用:

815e7574513a907d7eedcbafe2ff8b49.png

createConnect函数

connect函数最终调用的是connectHOC:

  • connectHOC其实是connectAdvanced的函数;
  • connectAdvanced函数最终返回的是wrapWithConnect函数;
f2508b4de1542e8bf8537f62b00d72f7.png

image-20200713173338618

wrapWithConnect函数:

3b9645a8554faa15f8424d3a74cefbef.png

wrapWithConnect函数

d42e7ea3e78038d96f8e9e3e06fb99a4.png

wrapWithConnect最终的返回值

我是@半糖学前端 ,一个前端从业者,专注前端技术领域分享,关注我和我一起学习,共同进步!

http://www.lbrq.cn/news/3259.html

相关文章:

  • 网站建设发布实训总结/市场营销方案
  • 网站模版怎么样/网站推广工具
  • wordpress登录ftp/沧州seo推广
  • 高端品牌网站建设/焊工培训技术学校
  • 如何做网站滚动屏幕/冯耀宗seo课程
  • 征婚网站上拉业务做恒指期货/防止恶意点击软件管用吗
  • wordpress 不能更换主题/seo入门教程seo入门
  • 建立个人网站有什么好处/万网注册域名查询
  • 北京pk10网站开发/百度新版本更新下载
  • 自己做的网站怎么收藏本站/做网站怎么赚钱
  • 网站建网站建设专业/北京seo代理计费
  • wordpress文章在哪个文件夹/搜索引擎优化seo名词解释
  • 织梦可以做论坛网站吗/购买域名的网站
  • 想做个网站报价蔬菜价格怎么做/sem竞价托管公司
  • 自己做网站升seo/免费发广告的网站
  • 南宁网站建设 传导/腾讯云域名
  • 商业授权书/西安seo技术培训班
  • 免费做快闪网站/公司网站建设全包
  • 网站后台编辑器不能正常显示/营销策划方案怎么写?
  • wordpress做社交网站/荆门今日头条新闻发布
  • 做网站花多钱/廊坊百度关键词优化怎么做
  • 宁波网站建设方案联系方式/如何在手机上开自己的网站
  • 视频网站如何推广/惠州seo全网营销
  • 政府门户网站建设管理工作/长春百度网站快速排名
  • 17网站一起做网店潮汕档口/今日新闻最新10条
  • 微网站建设报价/重庆百度小额贷款有限公司
  • wordpress 获取二级栏目/seo优化服务是什么
  • 做网站时间/百度竞价怎么做效果好
  • 网站建设购物车/郑州竞价托管
  • 婚纱摄影网站设计案例/写文章免费的软件
  • 开箱即用的Next.js SSR企业级开发模板
  • 电商项目_性能优化_数据同步
  • 机试01-C++基础语法与库函数
  • 宝塔服务器挂载数据盘
  • 【数据结构入门】顺序表
  • 【Django】-1- 开发项目搭建