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

大学学风建设专题网站wordpress输出友情链接

大学学风建设专题网站,wordpress输出友情链接,个人网站可以做资讯吗?,网站付的保证金怎么做会计凭证作者 | #x1f47d;来源 | 前端Sharing前言之前有朋友问我#xff0c;React Hooks 能否解决 React 项目状态管理的问题。这个问题让我思索了很久#xff0c;最后得出的结论是#xff1a;能#xff0c;不过需要两个自定义 hooks 去实现。那么具体如何实现的呢#xff1f;… 作者 | 来源 | 前端Sharing前言之前有朋友问我React Hooks 能否解决 React 项目状态管理的问题。这个问题让我思索了很久最后得出的结论是能不过需要两个自定义 hooks 去实现。那么具体如何实现的呢那就是今天要讲的内容了。通过本文你能够学习以下内容useContext useRef useMemouseEffect 的基本用法。如何将不同组件的自定义 hooks 建立通信共享状态。合理编写自定义 hooks 分析 hooks 之间的依赖关系。自定义 hooks 编写过程中一些细节问题。带着如上的知识点开启阅读之旅吧设计思路首先看一下要实现的两个自定义 hooks 具体功能。useCreateStore 用于产生一个状态 Store 通过 context 上下文传递 为了让每一个自定义 hooks useConnect 都能获取 context 里面的状态属性。useConnect 使用这个自定义 hooks 的组件可以获取改变状态的 dispatch 方法还可以订阅 state 被订阅的 state 发生变化组件更新。如何让不同组件的自定义 hooks 共享状态并实现通信呢首先不同组件的自定义 hooks 可以通过 useContext 获得共有状态而且还需要实现状态管理和组件通信那么就需要一个状态调度中心来统一做这些事可以称之为 ReduxHooksStore 它具体做的事情如下全局管理 state state 变化通知对应组件更新。收集使用 useConnect 组件的信息。组件销毁还要清除这些信息。维护并传递负责更新的 dispatch 方法。一些重要 api 要暴露给 context 上下文传递给每一个 useConnect。1、useCreateStore 设计首先 useCreateStore 是在靠近根部组件的位置的 而且全局只需要一个目的就是创建一个 Store 并通过 Provider 传递下去。使用const store  useCreateStore( reducer , initState )参数reducer 全局 reducer纯函数传入 state 和 action 返回新的 state 。initState 初始化 state 。返回值为 store 暴露的主要功能函数。2、Store设计Store 为上述所说的调度中心接收全局 reducer 内部维护状态 state 负责通知更新 收集用 useConnect 的组件。const Store  new ReduxHooksStore(reducer,initState).exportStore()参数接收两个参数透传 useCreateStore 的参数。3、useConnect设计使用 useConnect 的组件将获得 dispatch 函数用于更新 state 还可以通过第一个参数订阅 state 被订阅的 state 改变 会让组件更新。// 订阅 state 中的 number  const mapStoreToState  (state)({ number: state.number  }) const [ state , dispatch ]  useConnect(mapStoreToState)参数mapStoreToState将 Store 中 state 映射到组件的 state 中可以做视图渲染使用。如果没有第一个参数那么只提供 dispatch 函数不会订阅 state 变化带来的更新。返回值返回值是一个数组。数组第一项为映射的 state 的值。数组第二项为改变 state 的 dispatch 函数。4、原理图7.jpguseCreateStoreexport const ReduxContext  React.createContext(null) /* 用于产生 reduxHooks 的 store */ export function useCreateStore(reducer,initState){const store  React.useRef(null)/* 如果存在——不需要重新实例化 Store */if(!store.current){store.current   new ReduxHooksStore(reducer,initState).exportStore()}return store.current }useCreateStore 主要做的是接收 reducer 和 initState 通过 ReduxHooksStore 产生一个 store 不期望把 store 全部暴露给使用者只需要暴露核心的方法所以调用实例下的 exportStore抽离出核心方法。使用一个 useRef 保存核心方法传递给 Provider 。状态管理者 —— ReduxHooksStore接下来看一下核心状态 ReduxHooksStore 。import { unstable_batchedUpdates } from react-dom class ReduxHooksStore {constructor(reducer,initState){this.name  __ReduxHooksStore__this.id  0this.reducer  reducerthis.state  initStatethis.mapConnects  {}}/* 需要对外传递的接口 */exportStore(){return {dispatch:this.dispatch.bind(this),subscribe:this.subscribe.bind(this),unSubscribe:this.unSubscribe.bind(this),getInitState:this.getInitState.bind(this)}}/* 获取初始化 state */getInitState(mapStoreToState){return mapStoreToState(this.state)}/* 更新需要更新的组件 */publicRender(){unstable_batchedUpdates((){ /* 批量更新 */Object.keys(this.mapConnects).forEach(name{const { update }  this.mapConnects[name]update(this.state)})})}/* 更新 state  */dispatch(action){this.state  this.reducer(this.state,action)// 批量更新this.publicRender()}/* 注册每个 connect  */subscribe(connectCurrent){const connectName  this.name  (this.id)this.mapConnects[connectName]   connectCurrentreturn connectName}/* 解除绑定 */unSubscribe(connectName){delete this.mapConnects[connectName]} }状态reducer这个 reducer 为全局的 reducer 由 useCreateStore 传入。state全局保存的状态 state 每次执行 reducer 会得到新的 state 。mapConnects里面保存每一个 useConnect 组件的更新函数。用于派发 state 改变带来的更新。方法负责初始化getInitState这个方法给自定义 hooks 的 useConnect 使用用于获取初始化的 state 。exportStore这个方法用于把 ReduxHooksStore 提供的核心方法传递给每一个 useConnect 。负责绑定解绑subscribe绑定每一个自定义 hooks useConnect 。unSubscribe解除绑定每一个 hooks 。负责更新dispatch这个方法提供给业务组件层每一个使用 useConnect 的组件可以通过 dispatch 方法改变 state 内部原理是通过调用 reducer 产生一个新的 state 。publicRender当 state 改变需要通知每一个使用 useConnect 的组件这个方法就是通知更新至于组件需不需要更新那是 useConnect  内部需要处理的事情这里还有一个细节就是考虑到 dispatch 的触发场景可以是异步状态下所以用 React-DOM 中 unstable_batchedUpdates 开启批量更新原则。useConnectuseConnect 是整个功能的核心部分它要做的事情是获取最新的 state 然后通过订阅函数 mapStoreToState 得到订阅的 state 判断订阅的 state 是否发生变化。如果发生变化渲染最新的 state 。export function useConnect(mapStoreToState(){}){/* 获取 Store 内部的重要函数 */const contextValue  React.useContext(ReduxContext)const { getInitState , subscribe ,unSubscribe , dispatch }  contextValue/* 用于传递给业务组件的 state  */const stateValue  React.useRef(getInitState(mapStoreToState))/* 渲染函数 */const [ , forceUpdate ]  React.useState()/* 产生 */const connectValue  React.useMemo((){const state   {/* 用于比较一次 dispatch 中新的 state 和 之前的state 是否发生变化  */cacheState: stateValue.current,/* 更新函数 */update:function (newState) {/* 获取订阅的 state */const selectState  mapStoreToState(newState)/* 浅比较 state 是否发生变化如果发生变化 */const isEqual  shallowEqual(state.cacheState,selectState)state.cacheState  selectStatestateValue.current   selectStateif(!isEqual){/* 更新 */forceUpdate({})}}}return state},[ contextValue ]) // 将 contextValue 作为依赖项。React.useEffect((){/* 组件挂载——注册 connect */const name   subscribe(connectValue)return function (){/* 组件卸载 —— 解绑 connect */unSubscribe(name)}},[ connectValue ]) /* 将 connectValue 作为 useEffect 的依赖项 */return [ stateValue.current , dispatch ] }初始化用 useContext 获取上下文中 ReduxHooksStore 提供的核心函数。用 useRef 来保存得到的最新的 state 。用 useState 产生一个更新函数 forceUpdate 这个函数只是更新组件。注册解绑流程注册通过 useEffect 来向 ReduxHooksStore 中注册当前 useConnect 产生的 connectValue connectValue 是什么马上会讲到。subscribe 用于注册会返回当前 connectValue 的唯一标识 name 。解绑在 useEffect 的销毁函数中可以用调用 unSubscribe 传入 name 来解绑当前的 connectValueconnectValue是否更新组件connectValue 真正地向 ReduxHooksStore 注册的状态首先用 useMemo 来对 connectValue 做缓存connectValue 为一个对象里面的 cacheState 保留了上一次的 mapStoreToState 产生的 state 还有一个负责更新的 update 函数。更新流程 当触发 dispatch 在 ReduxHooksStore 中会让每一个 connectValue 的 update 都执行 update 会触发映射函数 mapStoreToState 来得到当前组件想要的 state 内容。然后通过 shallowEqual 浅比较新老 state 是否发生变化如果发生变化那么更新组件。完成整个流程。shallowEqual 这个浅比较就是 React 里面的浅比较在第 11 章已经讲了其流程这里就不讲了。分清依赖关系首先自定义 hooks useConnect 的依赖关系是上下文 contextValue 改变那么说明 store 发生变化所以重新通过 useMemo 产生新的 connectValue 。所以 useMemo 依赖 contextValue。connectValue 改变那么需要解除原来的绑定关系重新绑定。useEffect 依赖 connectValue。局限性整个 useConnect 有一些局限性比如没有考虑 mapStoreToState 可变性无法动态传入 mapStoreToState 。浅比较不能深层次比较引用数据类型。使用与验证效果接下来就是验证效果环节我模拟了组件通信的场景。根部组件注入 Storeimport { ReduxContext , useConnect , useCreateStore } from ./hooks/useRedux function  Index(){const [ isShow , setShow ]   React.useState(true)console.log(index 渲染)return divCompA /CompB /CompC /{isShow   CompD /}button onClick{()  setShow(!isShow)} 点击/button/div }function Root(){const store  useCreateStore(function(state,action){const { type , payload } actionif(type  setA ){return {...state,mesA:payload}}else if(type  setB){return {...state,mesB:payload}}else if(type  clear){ //清空return  { mesA:,mesB: }}else{return state}},{ mesA:111,mesB:111 })return divReduxContext.Provider value{store} Index//ReduxContext.Provider/div }Root根组件通过 useCreateStore 创建一个 store 传入 reducer 和 初始化的值 { mesA:111,mesB:111 }用 Provider 传递 store。Index组件有四个子组件 CompA CompB CompC CompD 。其中 CompD 是 动态挂载的。业务组件使用function CompA(){const [ value ,setValue ]  useState()const [state ,dispatch ]  useConnect((state) ({ mesB : state.mesB }) )return div classNamecomponent_box p 组件A/pp组件B对我说  {state.mesB} /pinput onChange{(e)setValue(e.target.value)}placeholder对B组件说/button onClick{() dispatch({ type:setA ,payload:value })} 确定/button/div }function CompB(){const [ value ,setValue ]  useState()const [state ,dispatch ]  useConnect((state) ({ mesA : state.mesA }) )return div classNamecomponent_box p 组件B/pp组件A对我说  {state.mesA} /pinput onChange{(e)setValue(e.target.value)}placeholder对A组件说/button onClick{() dispatch({ type:setB ,payload:value })} 确定/button/div }function CompC(){const [state  ]  useConnect((state) ({ mes1 : state.mesA,mes2 : state.mesB }) )return div classNamecomponent_box p组件A  {state.mes1} /pp组件B  {state.mes2} /p/div }function CompD(){const [ ,dispatch  ]  useConnect( )console.log(D 组件更新)return div classNamecomponent_box button onClick{() dispatch({ type:clear })}  清空 /button/div }CompA 和 CompB 模拟组件双向通信。CompC 组件接收 CompA 和 CompB 通信内容并映射到 mes1 mes2 属性上。CompD 没有 mapStoreToState 没有订阅 state state 变化组件不会更新只是用 dispatch 清空状态。效果总结本文通过两个自定义 hooks 实现了 React-Redux 的基本功能这个模式在真实项目中可以使用吗我觉得如果是小型项目是完全可以使用的对于大型项目还是用 React Redux 或者其他成熟的状态管理工具。往期推荐如何跨 Namespace 同步 Secret 和 ConfigMap掘地三尺搞定 Redis 与 MySQL 数据一致性问题Redis 内存满了怎么办这样置才正确云原生的本手、妙手和俗手点分享点收藏点点赞点在看
http://wiki.neutronadmin.com/news/24555/

相关文章:

  • 极致优化WordPress网站速度网站制作和设计需要多少钱
  • 上海哪家做网站好装修公司网站 源码
  • linux网站服务器配置网站建设方案包括哪些内容
  • 网站建站上海百度站长工具是什么意思
  • 东营建设网站wordpress 安装插件
  • 做漫画网站湖南邵阳建设局网站
  • 合肥专业网站建设流行网站开发框架
  • 汕头网站时优化前端入职一周被劝退
  • 品牌网站建设教程wordpress 简约论坛
  • 杭州设计企业网站高端公司宁波建设网谢家限价期房2004
  • 找活做的网站定制杯子
  • 丽江网站设计公司访问数据库的网站开发语言
  • 南宁网站建设教学软件开发公司组织结构图
  • 游戏类网站备案需要前置审批吗什邡市建设局门户网站
  • 左侧导航栏网站做棋牌网站违法吗
  • 深圳外包公司网站登录背景图片素材
  • 青岛网站建设方案策划东莞网站开发推荐
  • 自动做网站的ai免费logo设计生成器下载
  • 济南网站开发推广公众号平台登录
  • 腾讯云如何创建网站购物网站的详细设计
  • 网站建设目录规范怎样建官方网站
  • 注册万网后网站怎么赚钱的asp.net网站搬迁到移动终端
  • 怎么搭建一个完整的网站自己家的电脑宽带50m做网站服务器
  • 成都创新网站建设有什么网站可以免费建站
  • 河南省建设工程质监总站网站织梦和wordpress能共存
  • 普通人怎么样做网站设计公司灰白色调网站
  • wdcp网站迁移接效果图做网站
  • 几百的网站网站ui升级怎么做
  • 建教会网站的内容广告制作简介
  • wordpress 2013如何进行网站性能优化?