美文网首页
React 基础知识点

React 基础知识点

作者: 阿羡吖 | 来源:发表于2020-02-21 17:11 被阅读0次

    一、React编程优势以及特点

    优势

    1.声明式开发 节约大量DOM操作
    2.可以与其他框架并存,如JQuery
    3.组件化(包含无状态组件)
    4.单向数据流 React父组件向子组件传值,子组件可以使用父组件传过来的值,但是不能直接修改父组件的内容
    5.视图层框架 只着重于数据和页面渲染,大型项目 需要借助如 redux等来进行组件之间的传值、通信
    6.函数式编程 维护程度简单、各司其职;便于代码自动化测试

    不足

    1、react中只是MVC模式的view部分,要依赖引入很多其他模块开发
    2、当父组件进行重新渲染操作时,即使子组件的props或state没有做出任何改变,也会同样进行重新渲染。

    特点

    1、声明式设计:React采用声明方式,可以轻松描述应用
    2、高效:React通过对DOM的模拟,最大限度的减少了与DOM的交互
    3、灵活:React可以与已知的库或框架很好地配合

    二、React零碎知识点(随时补充)

    1、构造函数的固定写法
    constructor(props){
      super(props);
      this.state = {
        //定义一些 页面初始化的状态型如
        inputValue:"",
        list:[]
      }
    }
    //在页面初始化的时候,construcotr构造函数会优于其他函数最早被执行
    
    2、htmlFor、dangerousSetInnerHTML的意义与使用
      <div>
          //htmlFor可以使用户再点击输入内容的时候光标自动显示在input中,如下图
          <label htmlFor="insertArea">请输入内容</label>
          <input id="insertArea" />
      </div>
    
    htmlFor.gif
    <ul>
    // dangerouslySetInnerHTML 不转义标签 保留标签属性及样式
        {
           this.state.list.map((item, index) =>{
               return <li dangerouslySetInnerHTML = {{__html:item}}></li>
           })
        } 
    </ul>
    
    dangerouslySetInnerHTML.gif
    3、父子组件的传值方式(不仅限于传值,还可以传递方法)
    // content、index 为内容和索引;handleItemDel为方法
      this.state.list.map((item,index) => {
          return  (
              <TodoItem  content={item} index={index} handleItemDel= {this.handleItemDelClick} />
        )
      })
    
    4、对于直接写在展示内容中的逻辑处理
      可以使用一个函数,把逻辑处理放到函数中,便于代码优化
      class TodoList extends Component{
        ......
        render(){
          return (
            <div>
              {this.getTodoItem()}
            </div>
          )
        }
        getTodoItem(){
          //TodoItem为一个子组件
          return this.state.list.map((item,index) =>{
            <TodoItem  content={item} index={index} />
          })
        }
      }
    
    5、对于初始化状态值的操作。
    react 对于初始化定义得状态值的操作使用this.setState
    handeleBtnClick(){
    //prevState表示修改前的数据 等价于this.state.list
    //...es6的展开运算,...prevState.list 相等于拷贝this.state.list
      this.setState((prevState) =>({
        list:[...prevState.list,.....]
      }))
    }
    
    6、propType与defaultProps

    propType限制要求父组件向子组件传值类型

    // 父组件部分代码
    import PropTypes from 'prop-types' //属性接收的强校验 脚手架工具自带
    <TodoItem content={item} index={index}  handleItemDelete={this.handleItemDelete} />
    //子组件部分代码
    TodoItem.propTypes = { 
        test:PropTypes.string.isRequired, // 要求 test 是字符串 必传
        content: PropTypes.string, // 要求content 必须是字符串
        handleItemDelete:PropTypes.func, // handleItemDelete 必须是函数
        index:PropTypes.number  
    }
    

    defaultProps默认属性值。在页面初始化时,可以给某一个或某一些元素定义一个默认值。如上述代码test父组件未给子组件传递,而且规定其为必传项,这时控制台会出现警告或报错,因此就需要用到defaultProps

    TodoItem.defaultProps = {
        test:'Hello'
    } 
    
    7、虚拟DOM

    普通实现:
    1、state 数据(constructor 下初始化的数据)
    2、JSX模板 (jsx代码)
    3、数据+模板 结合,生成真实DOM,来显示
    4、state 发生改变
    5、数据+模板 结合,生成真实DOM,替换原始DOM
    缺陷:
    第一次生成了一个完成的DOM片段
    第二次生成了一个完整的DOM片段
    第二次的DOM替换第一次的DOM,非常耗性能

    改良:
    1、state 数据(constructor 下初始化的数据)
    2、JSX模板 (jsx代码)
    3、数据+模板 结合,生成真实DOM,来显示
    4、state 发生改变
    5、数据+模板 结合,生成真实DOM,并不直接替换原始DOM
    6、新的DOM和原始DOM作比对 找差异
    7、找出DOM发生的变化
    8、只用新的DOM发生变化的部分 替换掉老的DOM中的部分
    缺陷:性能提升并不明显

    React 虚拟DOM
    1、state 数据(constructor 下初始化的数据)
    2、JSX模板 (jsx代码)
    3、数据+ 模板 生成虚拟DOM(虚拟DOM就是一个JS对象,用它来描述真实DOM)
    ['div',{id:'abc'},['span',{},'hello world']](表述上面DOM对象)
    4、用虚拟DOM的结构生成真实DOM,来显示
    <div id="abc"><span>hello world</span></div>
    5、state 发生改变
    6、数据+ 模板 生成新的虚拟DOM(极大的提升了性能)(react 虚拟DOM 为同层比对)
    ['div',{id:'abc'},['span',{},'bye bye']]
    7、比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容(极大的提升了性能)
    8、直接操作DOM、改变span中的内容
    优点:
    1、性能得到提升
    2、使得跨端应用得以实现。React Native

    ref

    帮助我们在react中直接获取DOM元素使用的 一般情况,尽量不要使用,除非非用不可

    class TodoList extends Component {
      constructor(props){
        super(props);
          this.state = {
            inputValue:'',
            list:[]
           }
         this.handleInputChange = this.handleInputChange.bind(this)
         this.handleBtnClick = this.handleBtnClick.bind(this)
      }
      render(){
        return(
          <input
              id="insertArea"
              className='input'
              value={this.state.inputValue}
             onChange={this.handleInputChange}
              ref ={(input) =>{this.input = input}}
            />
          <button onClick={this.handleBtnClick}>提交</button>
        )
      }
       handleInputChange(e){
        const value = this.input.value 
      }
       handleBtnClick(){
         // prevState 指的是修改数据之前的那一次数据 等价于this.state 避免直接修改了state的状态
         this.setState((prevState) => ({
            list:[...prevState.list, prevState.inputValue],
            inputValue:''
        }),()=>{
              // setState 提供的第二个参数  当setState执行成功后执行 ref 获取DOM 操作改变内容在此执行
            });  
       }
    }
    

    生命周期函数

    是指函数在某一个时刻组件会自动调用执行的函数

    挂载部分
    componentWillMount当组件即将被挂载到页面的时刻自动执行
    render 页面渲染
    componentDidMount当组件被挂载到页面之后自动执行

    数据更新部分
    shouldComponentUpdate 组件被更新之前,会自动执行,返回一个布尔值。true/false
    componentWillUpdate 组件被更新之前,会自动执行,但它在shouldComponentUpdate之后被执行,如果 shouldComponentUpdate返回true,执行,返回false不执行
    componentDidUpdate 组件更新完成之后执行
    componentWillReceiveProps 当父组件传值props发生改变是触发
    执行条件如下:
    一个组件需要从父组件接收参数
    如果该组件第一次存在于父组件中,不会执行
    如果该组件之前已经存在于父组件中,才会自行
    componentWillUnmount 当组件即将从页面中移除的时候去执行

    diff算法

    1、把树形结构按照层级分解,只比较同级元素
    2、通过给列表结构的每个单个元素添加唯一key值进行区分同层次的子节点的比较
    3、React只会匹配相同 class 的component(这里的class指的是组件的名字)
    4、合并操作,调用component的setState方法的时候,React将其标记为dirty 到每一个事件循环结束,React检查所有标记dirty的component重新绘制
    5、选择性渲染。开发人员可以重写shouldComponentUpdate提高diff的性能

    image.png
    React组件之间的传值

    父子组件:父传子 props;子传父:子组件调用父组件中的函数并传参
    兄弟:利用redux实现
    所有关系都通用的方法:利用Pubsub.js 订阅

    setState()为异步的考量
    1、保证内部的一致性

    因为props是要等到父组件渲染完成 过后才能拿到,也就是说不能同步更新,state出于统一性设计成异步

    2、性能优化

    同步会导致运行阻塞,延迟

    3、支持state在幕后渲染

    异步可以使state在幕后更新,而不影响你当前旧页面的交互,提神用户体验

    React性能优化

    1、充分利用shouldComponentUpdate函数,不过前提保证你的组件尽量短小精悍,如果当前组件过于庞大复杂,其实也是很难有优化的操作
    2、给DOM遍历上添加唯一的key,注意尽量不要使用index,因为如果你新的DOM中删除了某一个节点,它会重新排列index。导致和原来数据完全不一样,而重新渲染,所以最好使用id什么的来做key值
    3、能使用const声明的尽量使用const
    4、DOM里少用箭头函数,当然其实要传参时要用还得用,再者,函数bind尽量写在constructor,避免每次render重新bind
    5、减少对真实DOM的操作
    6、如果使用webpack搭建环境的话 当一个包过大加载过慢时,可分打成多和个包来优化(未测试)

    React与vue的对比
    相同点

    1、都是虚拟DOM的操作实现快速渲染
    2、父子、兄弟之间通信相近,都有自己的状态管理器react=>redux, vue=>vuex
    3、都是轻量级的应用框架
    4、现在vue也渐渐吸收了一些React中的语法,比如JSX语法 类式生命写法等

    不同

    1、React属于单项数据流--MVC模式,vue则属于双向数据流---MVVM模式
    2、react兼容性比vue好,vue不兼容IE8
    3、React采用JSX语法,vue采用的是html模板语法
    4、vue的css可以有组件的私有作用域。React没有

    相关文章

      网友评论

          本文标题:React 基础知识点

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