美文网首页
2019-05-11 React小书 学习笔记(三)

2019-05-11 React小书 学习笔记(三)

作者: 追夢的蚂蚁 | 来源:发表于2019-05-13 12:36 被阅读0次

    http://huziketang.mangojuice.top/books/react/
    React小书
    以下内容都是基于React小书的


    什么是高阶组件

    高阶组件就是一个函数,传给它一个组件,它返回一个新的组件
    const NewComponent = higherOrderComponent(OldComponent)

    wrapWithLoadData高阶组件

    总结

    高阶组件就是一个函数,传给它一个组件,它返回一个新的组件。新的组件使用传入的组件作为子组件。

    高阶组件的作用是用于代码复用,可以把组件之间可复用的代码、逻辑抽离到高阶组件当中。新的组件和传入的组件通过 props 传递信息


    React 的 context

    context 打破了组件和组件之间通过 props 传递数据的规范,极大地增强了组件之间的耦合性。而且,就如全局变量一样,context 里面的数据能被随意接触就能被随意修改,每个组件都能够改 context 里面的内容会导致程序的运行不可预料。
    context - demo

    但是这种机制对于前端应用状态管理来说是很有帮助的,因为毕竟很多状态都会在组件之间进行共享,context 会给我们带来很大的方便。一些第三方的前端应用状态管理的库(例如 Redux)就是充分地利用了这种机制给我们提供便利的状态管理服务。但我们一般不需要手动写 context,也不要用它,只需要用好这些第三方的应用状态管理库就行了。


    动手实现Redux(一)优雅的修改共享状态

    一个可以被不同模块任意修改共享的数据状态就是魔鬼,一旦数据可以任意修改,所有对共享状态的操作都是不可预料的(某个模块 appState.title = null 你一点意见都没有),出现问题的时候 debug 起来就非常困难,这就是老生常谈的尽量避免全局变量

    动手实现Redux(二)抽离store和监控数据变化

    现在我们有了一个比较通用的 createStore,它可以产生一种我们新定义的数据类型 store,通过 store.getState 我们获取共享状态,而且我们约定只能通过 store.dispatch 修改共享状态。store 也允许我们通过 store.subscribe 监听数据数据状态被修改了,并且进行后续的例如重新渲染页面的操作。

    动手实现 Redux(三):纯函数(Pure Function)简介

    纯函数:一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用

    纯函数易调试测试

    动手实现 Redux(四):共享结构的对象提高性能

    共享结构的对象

    const obj = {a:1,b:2} const obj2 = { ...obj }//=>{a:1,b:2}
    const obj2 = { ...obj } 其实就是新建一个对象 obj2,然后把 obj 所有的属性都复制到 obj2 里面,相当于对象的浅复制。上面的 obj 里面的内容和 obj2 是完全一样的,但是却是两个不同的对象。除了浅复制对象,还可以覆盖、拓展对象属性:
    const obj = {a:1,b:2} const obj2 = { ...obj ,b:3,c:4}//=>{a:1,b:3,c:4},覆盖了b,新增了c

    优化性能

    后面的 store.dispatch 导致的重新渲染都没有关于 content 的 Log 了。因为产生共享结构的对象,新旧对象的 content 引用指向的对象是一样的,所以触发了 renderContent 函数开头的:

    ...
      if (newContent === oldContent) return
    ...
    

    动手实现 Redux(五):不要问为什么的 reducer

    createStore 接受一个叫 reducer 的函数作为参数,这个函数规定是一个纯函数,它接受两个参数,一个是 state,一个是 action。

    reducer 是不允许有副作用的。你不能在里面操作 DOM,也不能发 Ajax 请求,更不能直接修改 state,它要做的仅仅是 —— 初始化和计算新的 state

    动手实现 Redux(六):Redux 总结

    我们从一个简单的例子的代码中发现了共享的状态如果可以被任意修改的话,那么程序的行为将非常不可预料,所以我们提高了修改数据的门槛:你必须通过 dispatch 执行某些允许的修改操作,而且必须大张旗鼓的在 action 里面声明。

    这种模式挺好用的,我们就把它抽象出来一个 createStore,它可以产生 store,里面包含 getState 和 dispatch 函数,方便我们使用。

    后来发现每次修改数据都需要手动重新渲染非常麻烦,我们希望自动重新渲染视图。所以后来加入了订阅者模式,可以通过 store.subscribe 订阅数据修改事件,每次数据更新的时候自动重新渲染视图。

    接下来我们发现了原来的“重新渲染视图”有比较严重的性能问题,我们引入了“共享结构的对象”来帮我们解决问题,这样就可以在每个渲染函数的开头进行简单的判断避免没有被修改过的数据重新渲染。

    我们优化了 stateChanger 为 reducer,定义了 reducer 只能是纯函数,功能就是负责初始 state,和根据 state 和 action 计算具有共享结构的新的 state。

    createStore 现在可以直接拿来用了,套路就是:

    // 定一个 reducer
    function reducer (state, action) {
      /* 初始化 state 和 switch case */
    }
    
    // 生成 store
    const store = createStore(reducer)
    
    // 监听数据变化重新渲染页面
    store.subscribe(() => renderApp(store.getState()))
    
    // 首次渲染页面
    renderApp(store.getState()) 
    
    // 后面可以随意 dispatch 了,页面自动更新
    store.dispatch(...)
    

    动手实现 React-redux(一):初始化工程
    “主题色”

    动手实现 React-redux(二):结合 context 和 store

    动手实现 React-redux(三):connect 和 mapStateToProps

    动手实现 React-redux(四):mapDispatchToProps

    动手实现 React-redux(五):Provider
    React-redux 总结:
    1什么是React-redux,
    2为什么要 connect,
    3为什么要 mapStateToProps 和mapDispatchToProps,
    4什么是 Provider,
    我们通过解决一个个问题就知道它们到底为什么要这么设计的了。

    1. connect 函数和 Provider 容器组件。这就是 React-redux 的基本内容
    2. 我们尝试通过构建一个高阶组件 connect 函数的方式,把所有的重复逻辑和对 context 的依赖放在里面 connect 函数里面,而其他组件保持 Pure(Dumb) 的状态,让 connect 跟 context 打交道,然后通过 props 把参数传给普通的组件。
    3. 每个组件需要的数据和需要触发的 action 都不一样,所以调整 connect,让它可以接受两个参数 mapStateToProps 和 mapDispatchToProps,分别用于告诉 connect 这个组件需要什么数据和需要触发什么 action。
    4. 最后为了把所有关于 context 的代码完全从我们业务逻辑里面清除掉,我们构建了一个 Provider 组件。Provider 作为所有组件树的根节点,外界可以通过 props 给它提供 store,它会把 store 放到自己的 context 里面,好让子组件 connect 的时候都能够获取到。

    Smart 组件 vs Dumb 组件

    我们规定:所有的 Dumb 组件都放在 components/ 目录下,所有的 Smart 的组件都放在 containers/ 目录下,这是一种约定俗成的规则。

    Dumb 基本只做一件事情 —— 根据 props 进行渲染。而 Smart 则是负责应用的逻辑、数据,把所有相关的 Dumb(Smart)组件组合起来,通过 props 控制它们。

    Smart 组件可以使用 Smart、Dumb 组件;而 Dumb 组件最好只使用 Dumb 组件,否则它的复用性就会丧失。

    要根据应用场景不同划分组件,如果一个组件并不需要太强的复用性,直接让它成为 Smart 即可;否则就让它成为 Dumb 组件。

    还有一点要注意,Smart 组件并不意味着完全不能复用,Smart 组件的复用性是依赖场景的,在特定的应用场景下是当然是可以复用 Smart 的。而 Dumb 则是可以跨应用场景复用,Smart 和 Dumb 都可以复用,只是程度、场景不一样。


    相关文章

      网友评论

          本文标题:2019-05-11 React小书 学习笔记(三)

          本文链接:https://www.haomeiwen.com/subject/cjyxaqtx.html