react知识点梳理

作者: 别过经年 | 来源:发表于2017-08-12 00:58 被阅读68次
    1.immutable

    连续看了两三篇关于immutable.js的文章,传统的object和array等引用类型是mutable数据,就是当赋值的时候,指向同个内存,这在react更新机制里面就会出现个问题,引用是相同的,react purecomponent就会检测不出前后两个props的不同部分,就不会re-render,而React.Component是可以检测出来props的更新的,然后就会re-render,比如一个组件的props改变(数据流是单向的)该组件的props改变只需要其对应的父组件更新就可以了,不需要该组件的兄弟组件及其子组件更新,因为原生js引用类型共享内存,这些组件都会更新,这是我们不想看到的,所以引入了immutable.js共享部分内存,把直接相关的节点更新就可以了。

    Immutable.js 以及在 react+redux 项目中的实践
    react Performance Tools 入门
    使用immutable优化React

    2. 模块或者组件按需加载

    React Loadable 简介
    webpack 构建性能优化策略小结
    react项目优化之webpack
    react-router按需加载(V4版)

    使用import()实现组件的按需加载

    根据点击的链接会在head标签里插入



    发现个很有趣的现象,点击About链接或者DashBoard链接两个组件相互切换,在同个页面的路由组件,路由切换的话,前面一个渲染好的组件会Unmount,即被卸载
    例如路由about->dashboard,About组件会被卸载(componentWillUnmount被调用),DashBoard被装载(componentWillMount被调用),


    由下图可以看出,路由导航到dashboard的时候About组件并没有被包含在其Route组件里,也就是切换路由的时候About被卸载了,移出了dom

    仓库:assassin / react-starter

    参考:

    在react-router4中进行代码拆分(基于webpack)
    HTML5 <script>元素async,defer异步加载

    3.试读react-redux源码

    本文的react-redux代码本版为5.0.6

    阮一峰的Redux 入门教程(三):React-Redux 的用法

    class VisibleTodoList extends Component {
      componentDidMount() {
        const { store } = this.context;
        this.unsubscribe = store.subscribe(() =>
          this.forceUpdate()
        );
      }
    
      render() {
        const props = this.props;
        const { store } = this.context;
        const state = store.getState();
        // ...
      }
    }
    
    VisibleTodoList.contextTypes = {
      store: React.PropTypes.object
    }
    

    React-Redux自动生成的容器组件的代码,就类似上面这样,从而拿到store
    这句话不是很理解,对比了下官方给出的代码:

    import { connect } from 'react-redux'
    import { toggleTodo } from '../actions'
    import TodoList from '../components/TodoList'
    
    const getVisibleTodos = (todos, filter) => {
      switch (filter) {
        case 'SHOW_ALL':
          return todos
        case 'SHOW_COMPLETED':
          return todos.filter(t => t.completed)
        case 'SHOW_ACTIVE':
          return todos.filter(t => !t.completed)
        default:
          throw new Error('Unknown filter: ' + filter)
      }
    }
    
    const mapStateToProps = (state) => ({
      todos: getVisibleTodos(state.todos, state.visibilityFilter)
    })
    
    const mapDispatchToProps = {
      onTodoClick: toggleTodo
    }
    
    const VisibleTodoList = connect(
      mapStateToProps,
      mapDispatchToProps
    )(TodoList)
    
    export default VisibleTodoList
    

    和大神说的自动生成的容器组件的代码完全不同,现在的理解应该是connect以后得到的容器组件的代码,而不是现在我们看到的官网的容器组件的代码

    今天看到了connectAdvanced.js的最后一句卡住了return hoistStatics(Connect, WrappedComponent)
    import hoistStatics from 'hoist-non-react-statics'来自于hoist-non-react-statics具体干啥用的还不清楚,搜索它怎么用的时候发现了官网高阶组件里面提到了这个库,于是再次看了遍高阶组件的用法,如是说:高阶组件是一个函数,能够接受一个组件并返回一个新的组件,结合实际的react-redux的connect功能,

    import TodoList from '../components/TodoList'
    const VisibleTodoList = connect(
      mapStateToProps,
      mapDispatchToProps
    )(TodoList)
    

    connect.js


    connect.js

    connect.js调用了connectAdvanced.js
    connectAdvanced.js


    connectAdvanced.js connect()(TodoList)返回的新组件

    那么如果从高阶组件的定义高阶组件是一个函数,能够接受一个组件并返回一个新的组件来看connectAdvanced.js中的wrapWithConnect函数就是高阶组件,它接受了一个WrappedComponent组件返回了一个<Connect(TodoList)>...</Connect(TodoList)>新的组件

    displayName其实是组件的一个静态属性,如果在组件中定义则有,否则不会有该属性
    静态属性在es6的不同版本有不同的定义方式:

    export default class MainSection extends Component {
      static propTypes = {//先进的一种
        todos: PropTypes.array.isRequired,
        actions: PropTypes.object.isRequired
      }
    }
    //原始的一种
    MainSection.propTypes={
        todos: PropTypes.array.isRequired,
        actions: PropTypes.object.isRequired
    }
    

    到目前的理解,使用高阶组件的目的有

    • 抽取很多组件的公共方法和属性,类似于之前的mixin
    • 返回的新组件必须保留原始组件的功能(包括原始组件的静态方法和静态属性)
      connectAdvanced.js
    import hoistStatics from 'hoist-non-react-statics'
    
    export default function connectAdvanced(){
      return function wrapWithConnect(WrappedComponent) {
        class Connect extends Component {
       }
    
        Connect.WrappedComponent = WrappedComponent
        Connect.displayName = displayName
        Connect.childContextTypes = childContextTypes
        Connect.contextTypes = contextTypes
        Connect.propTypes = contextTypes
    
        if (process.env.NODE_ENV !== 'production') {
        }
    
        return hoistStatics(Connect, WrappedComponent)//原始组件的所有静态方法全部拷贝给新组件
      }
    }
    }
    

    上下文(Context)
    react-redux源码分析
    react-redux源码分析
    react-redux 源码解析

    一个有意思的发现:

    class Animal{
      constructor(){
        this.age=""
      }
      showAge(){
        console.info(this.age)
      }
      getName=()=>{
        return "name"  
      }
    }
    

    使用ts编译为js

    var Animal = /** @class */ (function () {
        function Animal() {
            this.getName = function () {
                return "name";
            };
            this.age = "";
        }
        Animal.prototype.showAge = function () {
            console.info(this.age);
        };
        return Animal;
    }());
    
    
    4.高阶组件的两种实现方式

    看这篇文章带着三个问题一起深入浅出React高阶组件的时候发现有个有趣的现象:父组件可以直接调用子组件的实例方法,这在Java中是不可能的,具体可查看Java 中父类怎么调用子类的方法?,这篇文章指出可以使用反射的方式,js真的不按套路出牌啊

    深入理解 React 高阶组件
    React进阶之高阶组件
    React高阶组件探究
    React 高阶组件(HOC)入门指南

    5.木偶组件和智能组件

    在 2017 年学习 React + Redux 的一些建议(上篇)

    react root组件下面应该放什么组件?

    6.按需加载 包括saga

    react结合redux和react-router开发大型应用实现按需加载(code spliting)
    React Router v4 之代码分割:从放弃到入门

    7.在代码提交之前需要对代码进行lint和语法检查

    需要用到库:
    okonet/lint-staged
    typicode/husky
    prettier/prettier

    从React脚手架工具学习React项目的最佳实践(上):前端基础配置
    前端开发如何让持续集成/持续部署(CI/CD)跑起来

    github 集成测试
    前端开源项目持续集成三剑客

    8.用js的方式改变子组件的props
    import RadioButton from './radioButton'
    children = React.Children.map(children, (child: any) => {
            if (child.type === RadioButton) {
              return React.cloneElement(child, {
                prefixCls: radioType === 'text' ? 'radio-text' : 'radio-button', //手动改变了prefixCls props
              })
            } else {
              return child
            }
          })
    

    React中props.children和React.Children的区别

    9. 在生产环境中使用LogRocket记录Redux日志

    相关文章

      网友评论

        本文标题:react知识点梳理

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