下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

web前端:自定义React-redux

作者:路飞910     来源: https://www.cnblogs.com/lufei910/p/12201055.html点击数:1217发布时间: 2020-03-31 09:11:53

标签: 渲染UIReact

Web开发

  React起源于Facebook的内部项目,因为该公司对市场上所有JavaScriptMVC框架,都不满意,就决定自己写一套,用来架设Instagram的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

  React主要用于构建UI。你可以在React里传递多种类型的参数,如声明代码,帮助你渲染出UI、也可以是静态的HTMLDOM元素、也可以传递动态变量、甚至是可交互的应用组件。

  实现mini版react-redux

  1.理解react-redux模块

  1).react-redux模块整体是一个对象模块

  2).包含2个重要属性:Provider和connect

  3).Provider

  值:组件类

  作用:向所有容器子组件提供全局store对象

  使用:<Providerstore={store}><Xxx/></Provider>

  4).connect

  值:高阶函数

  作用:包装组件生成容器组件,让被包装组件能与redux进行通信

  使用:connect(mapStateToProPS,mapDispatchToProps)(Xxx)

  2.context的理解和使用

  1).理解

  当你觉得多层传递props麻烦,可以选择使用context

  context是组件对象的一个属性,它的值是一个对象

  一个组件指定的context内数据,所有层次子组件都可以读取到

  如果可以尽量不用context,你可以选择使用react-redux,react-redux内部就利用了context

  2).使用

  父组件:

  staticchildContextTypes={

  color:PropTypes.string

  }

  getChildContext(){

  return{color:'red'};

  }

  后代组件:

  staticcontextTypes={

  color:PropTypes.string

  }

  render(){

  this.context.color

  }

  3.实现代码:src/libs/react-redux/index.js

  importReact,{Component}from'react'

  importPropTypesfrom'prop-types'

  /*

  1.Provider组件类

  */

  exportclassProviderextendsComponent{

  //声明当前组件接收store

  staticpropTypes={

  store:PropTypes.object.isRequired

  }

  //必须声明向子节点指定全局数据store

  staticchildContextTypes={

  store:PropTypes.object.isRequired

  }

  //指定向子组件指定全局数据store

  getChildContext(){

  return{store:this.props.store};

  }

  render(){

  //返回所有子节点(如果没有子节点返回undefined,如果只有一个子节点它是对象,如果有多个它是数组)

  returnthis.props.children

  }

  }

  /*

  2.connect方法

  */

  exportfunctionconnect(mapStateToProps=()=>null,mapDispatchToProps={}){

  //返回函数(接收被包装组件类作为参数)

  return(WrapComponent)=>{

  //返回一个新的组件类

  returnclassConnectComponentextendsComponent{

  //声明接收全局store

  staticcontextTypes={

  store:PropTypes.object.isRequired

  }

  //构造函数的第2个参数为context对象

  constructor(props,context){

  super(props)

  console.log('constructor',this.context)//此时组件对象中还没有context

  //从context中取出store

  const{store}=context

  //一般属性:调用mapStateToProps函数得到包含所有需要传递一般属性的集合对象

  conststateProps=mapStateToProps(store.getState())

  //分发action的函数属性:调用自定义的整合函数生成包含多个分发action的函数的对象

  constdispatchProps=this.bindActionCreators(mapDispatchToProps)

  //初始化状态,包含所有需要传递给WrapComponent组件的一般属性

  this.state={

  ...stateProps

  }

  //将包含dispatch函数的对象保存在组件对象上(不用放到state中)

  this.dispatchProps=dispatchProps

  }

  /*

  根据包含多个actioncreator的对象,返回一个包含多个分发action的函数的对象

  */

  bindActionCreators=(mapDispatchToProps)=>{

  //准备一个保存分发action函数的对象容器

  constdispatchProps={}

  //遍历每个actioncreator

  Object.keys(mapDispatchToProps).forEach((key)=>{

  //得到某个actioncreator

  constactionCreator=mapDispatchToProps[key]

  //定义包含分发action代码的函数,并只在到准备好的容器中

  dispatchProps[key]=(...args)=>{

  this.context.store.dispatch(actionCreator(...args))

  }

  })

  //返回dispatch代码函数容器对象

  returndispatchProps

  }

  componentDidMount(){

  console.log('componentDidMount',this.constructor)

  //得到store

  const{store}=this.context

  //订阅监听

  store.subscribe(()=>{

  //一旦store中的state有变化,更新组件状态,从而导致被包装组件重新渲染

  this.setState(mapStateToProps(store.getState()))

  })

  }

  render(){

  return<WrapComponent{...this.state}{...this.dispatchProps}/>

  }

  }

  }

  }

  由于React的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来Web开发的主流工具。

赞(11)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程