构建React基础知识体系

来自React文档,基础知识的盲点记录

2020-7-9 更新

  1. 增加React API功能说明、生命周期;
  2. 其他说明内容调整;
核心概念

核心基础知识。

标记:

  1. 所有内联函数的定义,都会导致组件重新渲染(在更新时渲染两次)。可以通过绑定函数的方式避免。
JSX
  1. ReactDom 使用小驼峰来定义标签的属性名称,比如classNameonClick etc.
  2. ReactDom 对所有输入的内容渲染到页面时,会进行转移,即可防止XSS攻击。
  3. JSX表达式最好使用()包裹,避免遇到自动插入分号陷阱。
  4. ReactDom.render()用于渲染组件到dom中; 可以多次使用,
  5. JSX语法是React.createElement(component,props,...children)语法糖。
    let myComponent = React.createElement(
        'MyComponent',
        {info:{name:"admin"}},
    );
    
  6. false/null/undefined/true都不会被渲染,他们可以作为表达式去决定渲染哪个UI。
组件

包括函数组件function、ES6的class语法。

  1. 自定义组件名称必须大写开头,区分原生HTML的标签。

  2. setState() 更新可能会是异步的(在组件中批量更新数据操作,会合并后进行更新)。

  3. setState()可以接收一个回调函数,函数参数:preStateprops . 可使用之前state的值。

    this.setState((preState,props)=>({
        name:preState.lastName+props.firstName
    }));
    
  4. setState()更新会合并原来的state对象,浅合并;覆盖原有的对象。

  5. 渲染列表的key可以不是全局唯一;但必须是兄弟间唯一。

  6. 受控组件 - 控制原生HTML表单元素的用户输入,以React数据绑定的方式控制取值。

  7. 组件的数据流向是单向的,可以通过父组件传递回调函数的方式,在子组件属性发生变化时,调用props.callback传递数据到父组件。

组件复用、继承

根据业务分割组件,嵌套渲染层级过多,考虑组件分割。

  1. 自定义组件插槽(slot),props.children进行渲染。

    <MyComponent user = {this.state.userInfo}>
        <img src={this.state.userInfo.avatar}>
    </MyComponent>
    
    
    // MyComponent.js
    render(){
        return (
            <div>
                {this.props.children}
            </div>
        )
    }
    
  2. 可将组件作为props属性传入到组件中。

    <MyComponent user={<UserInfo info={this.state.info} />} />
    
    // MyComponent.js
    render(){
        return (
            <div>
                {this.props.user}
            </div>
        )
    }
    
  3. 组合就是将多个单功能组件合并完成一项整体功能。

  4. React.lazy() 懒加载指定的组件。减小打包体积,优化加载;React.Suspense指定加载器,在组件未具备渲染条件。

    let MyComponent = React.lazy(()=>import("./MyComponent.js"));
    
    return (<React.Suspense>
    	<MyComponent />
    </React.Suspense>);
    
高级概念
  1. 代码分割:减小打包的体积,初始时加载必要的信息;懒加载其他动态导入的模块。

    // import 动态导入模块中使用的组件
    import("lodash").then(({isEqual,isEmpty})=>{
        //...
        console.log(isEmpty({}));
    });
    
    // React.lazy 动态导入需要的组件,支持默认导出
    
    const MyComponent = React.lazy(()=>import("./MyComponent.js"));
    

    使用webpack 开发项目时,代码分割参考打包工具 webpack 的配置。

  2. Context 用于无需给每层添加props,在组件间进行数据共享。可查看此文查看Context具体使用

    // 创建
    let MyContext = React.createContext(defaultValue);
    
    // 父组件中使用
    return (<MyContext.Provider value="admin">
        <ChildComponent />
    </MyContext.Provider>)
    
    // 子组件中使用
    ChildComponent.contextType = MyContext;
    
    return (<div>
        <p>{this.context}</p>
    </div>)
    
  3. 错误边界处理,捕获组件中发生的错误渲染备用UI。static getDerivedStateFromError() 用于渲染备用UI;componentDidCatch()用于打印错误信息。

    未作处理时,则会导致整个项目奔溃。

  4. refs提供给我们访问元素DOM节点的方式。

    // 创建
    this.myRef = React.createRef(null);
    
    // 使用 , 通过this.myRef.current 访问到 p dom 节点
    return (<div>
        <p ref={this.myRef}></p>
    </div>)
    

    可以用于class组件,获取实例;函数组件没有实例,可通过回调的方式这里有一个列子

  5. refs转发,将子组件的需要访问的DOM元素暴露出来。通过forwardRef((props,ref)=>{})转发

    // 父组件
    this.myRef = React.createRef(null);
    
    return (<div>
        <ChildComponet ref={this.myRef} />
    </div>)
    
    // 转发 ref 到目标元素
    const ChildComponent = React.forwardRef((props,ref)=>(
        <button ref={ref}>{props.name}</button>
    ));
    

    不做转发时,ref 指向的就是子组件的示例。

    需要注意的是,如果要隔层传递,每层都需要forwardRef转发,ref属性不作为props属性传递;也可自定义ref名称,在目标元素使用ref绑定

  6. React.Fragment用于在无需额外节点时,使用包裹子元素。短语法标识也可达到目的。

    return (<>
        <li>1</li>
    <>)
    

    React.Fragment 支持传入key 属性。

  7. 高阶组件(HOC)用于复用组件逻辑的一种技巧。将传入的组件附加其他特性,输出另一个组件。

  8. render props 用于在组件之间共享一个值为函数的props技术。解决在组件渲染的UI受父组件某些属性的影响的问题。

    // 父组件
    return (<div>
        {this.state.data.map(item=>
            <Child status={(status)=>
                        <Status />} 
                info={item} />)}
    </div>)
    
  9. Props-Types 做类型检查。

    import PropTypes from 'prop-types';
    
    MyComponent.propTypes = {
        render:PropTypes.func.isRequired
    }
    
  10. 非受控组件:除了可受控组件,还有无法做到受控的表单元素。比如:文件输入input[type='file']. 所有非受控组件可通过ref属性访问元素DOM ,获取节点输入值。

  11. Portals 用于渲染UI父组件之外 。ReactDom.createPortal(component,dom)接受一个react组件挂载到指定的DOM元素上。

    // 可形成类似结构
    <body>
    	<div id="root"></div>
    	<div id="portals-root"></div>
    </body
    

    虽然不是真正意义上的父子组件关系,但在react中可以捕获到来自portal冒泡上来的事件。

    可用于对话框、提示框等。

API
  1. React.PureComponent 不同于React.Component,PureComponent以浅层对比propsstate实现了shouldComponentUpdate()函数。
    仅当数据结构比较简单时使用,可以减少了组件的重复更新;如果数据结构层次深、复杂,则需要使用forceUpdate()强制更新。
  2. React.memo()高阶组件,类似PureComponent,但只适用于函数组件,检查对比props变化。接受第二个参数,自定义对比。
    React.memo(function MyComponent(props){
    	// 组件
    },function propsEqual(prevProps,props){
    	// 自定义对比
    	// 如果对比一致则返回 true;不一致返回 false。
    });
    

    不同于shouldComponentUpdate() 对比不同时返回true 标识更新;相同时true标识需要更新。

  3. React.cloneElement克隆一个新的React元素,返回的React元素新props与旧props浅合并;新的子元素会替代旧子元素;会保留原始元素的keyref.
  4. React.isValidElement()验证元素是否是React元素。
  5. React.Children用于处理this.props.children数据结构的方法。
    • .map遍历children,每个元素调用回调函数;返回数组,如果是null/undefined则不会返回数组,如果元素是Fragment不会被遍历。
    • forEach遍历,无返回;
    • count总数;
    • only验证是否只有一个子元素;如果不是则会跑出错误。
    • toArray以数组的方式扁平化children,
声明周期

按照组件实例创建执行顺序:

周期函数释义
挂载constructor()构造函数
static getDerivedStateFromProps(props,state)返回一个对象来更新state,处理一些由props决定的state值
render()class组件必须实现的函数,生成DOM
componentDidMount()组件挂载后调用。
更新static getDerivedStateFromProps
shouldComponentUpdate(nextProps,nextState)手动比较props,state,决定是否需要更新
render()
getSnapshotBeforeUpdate()渲染之前调用,返回某些值,将会传入下一个执行的周期函数
componentDidUpdate(prevProps,prevState,snapshot)组件更新后调用
卸载componentWillUnmount()组件卸载或销毁之前调用

过时的生命周期componentWillMount()/componentWillReceiveProps()/componentWillUpdate(),过时的原因说是在异步渲染中,被滥用,出现的问题更多。

Hooks

针对函数式组件提供使用React特性的特性。

查看常用hooks的使用说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heroboyluck

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值