机器人论坛
直播中

姬房有

9年用户 335经验值
私信 关注
[问答]

React优势,react学习笔记分享

1、React优势
react适合大型团队的开发,每个人负责自己的组件,开发完毕之后由react渲染到前端页面


回帖(2)

罗振炜

2020-10-27 18:31:30
2、什么是JSX
JavaScript与XML的结合,方便用html代码创建虚拟DOM,虚拟DOM不是真实的DOM节点,而是虚拟化的,他可以快速反应,不占用页面的渲染机制,而且快速反应我们的动作。
在JSX中


  • 当它遇到<就会把代码当做HTML语法来解析
  • 当它遇到{就会把代码当做JavaScript来解析

//渲染到哪里ReactDOM.render(, document.getElementById("root"))使用Fragment可以将最外层标签实现取消的效果
// import React, {Component} from 'react'import React, {Component, Fragment} from 'react'class Xiaojiejie extends Component {    render() {        return (            //
                           
                                                            
                            
  • 头部按摩
  •                         
  • 精油推背
  •                     
               
                {/*
*/}                    )    }}export default Xiaojiejie
3、什么是响应式设计?

React以数据为驱动,不进行(官方也不建议)DOM操作,只需要关心数据就好了。
增加数据怎么增加?
在构造函数中实现。
return{  // ........................  {/* 下面用this.state.inputValue = e.target.value会报错,需要进行绑定 */}    // ........................    )}    inputChange(e) {        // 但是通过这种方式,在页面上看不到数据有任何的变化        console.log(this)        // 下面会报错,this的指向是错误的,需要使用bind方法进行绑定才可以        // this.state.inputValue = e.target.value        // 同时数据的改变也不能用上面这种方式              this.setState({            inputValue: e.target.value        })    }4、父组件向子组件传值

就相当于增加服务这个功能,就是父组件向子组件传递参数。
首先创建一个js文件,命名为XiaojiejieItem,这是Xiaojiejie的子组件
import React, {Component} from "react";import "./style.css";// import Xiaojiejie from "./Xiaojiejie";class XiaojiejieItem extends Component {    // state = {}    render() {        return (            
  •                 {/*这种方式是写死的,不能实现参数传递*/}                小姐姐            
  •         );    }}export default XiaojiejieItem然后在父组件中,设置属性的key值,可以自定义命名,这里命名为content。

                                                                   
                                                                                {                        this.state.list.map((item, index) => {                            return (                                <                                    XiaojiejieItem                                    key={item + index}                                    content={item}                                />                            )                        })                    }               
    设置好之后,子组件通过this.props.key来接收传递过来的值,也就是content。

                
  •                             {/* 通过this.props接收子组件传递过来的值 */}                {this.props.content}            
  • this.props能接收所有的属性和方法。

    5、子组件向父组件传值

    react中,不允许子组件向父组件直接传值。
    可以通过下面这种绑定的形式来传值。
        render() {        return (            
  •                 {/*这种方式是写死的,不能实现参数传递*/}                {/*小姐姐*/}                {this.props.content}            
  •         );    }    handleClick() {        console.log(this.props.index)    }还有种方式是通过构造函数的方式,通过这种方式,对以后的性能优化会起到很好的作用。

        constructor(props) {        super(props);        this.handleClick = this.handleClick.bind(this)    }1) 子组件不能直接改变父组件的值

    删除。就是我们的demo中,通过点击数据,删除父组件中的数据。直接删除是不允许的。
    举报

    李建军

    2020-10-27 18:31:42
    6、三大重点

    1) 单向数据流

    父组件向子组件传递数据是单向的,只能传递给子组件,子组件不能修改数据。如果想要修改数据,需要在父组件中定义相关的方法,然后将该方法也传递给子组件,由子组件来调用。
    1、为什么需要单向数据流

    因为父组件可能有很多个子组件,如果子组件能随意修改父组件的数据,其他组件所拿到的数据也会一同被修改,会对其他组件产生影响。
    2) react与其他框架相结合

    可以结合jQuery来使用
       
                   
    服务满意
    3) 函数式编程

    优点


    • 每个函数执行相应的功能,使逻辑十分清晰,代码一目了然。
    • 极大的方便了代码的测试,更容易的实现前端的自动化测试。

        inputChange(e) {...}    // 增加列表    addList() {...}    // 删除列表    deleteItem(index) {...}7、开发利器

    1)chrome扩展程序——react developer tools


    • webstorm插件——react snippets

    8、props数据校验

    下面可以看到父组件向子组件传递参数时的情况,我们能够传递参数,但是没有对参数做任何校验和判断。后期极有可能出现业务逻辑错误,并且不容易找到。
                   
                          {                        this.state.list.map((item, index) => {                            return (                                <                                    XiaojiejieItem                                    key={item + index}                                    content={item}                                    index={index}                                    deleteItem={this.deleteItem.bind(this)}                                />                            )                        })                    }               
    父组件向子组件传值,就需要在子组件中引入并校验。

    import PropTypes from 'prop-types'数据校验时,需要把校验的程序写在类的外面
    class XiaojiejieItem extends Component {  ...}XiaojiejieItem.protoTypes = {    content: PropTypes.string,    index: PropTypes.number,    deleteItem: PropTypes.function}9、ref绑定

    Ref是一个获取DOM节点或 React元素实例的工具。在 React中 Ref提供了一种方式,允许用户访问DOM节点或者在render方法中创建的React元素。
    在React单项数据流中,props是父子组件交互的唯一方式。要修改一个子组件,需要通过的新的props来重新渲染。 但是在某些情况下,需要在数据流之外强制修改子组件。被修改的子组件可能是一个React组件实例,也可能是一个DOM元素。对于这两种情况,React 都通过 Refs的使用提供了具体的解决方案。
                   
      {                    this.ul = ul}}                >继续看
          addList() {      ......              /* 发现下面打印的长度总是少一个 */        console.log(this.ul.querySelectorAll('li').length)        /*        *        * setState是一个异步的方法,不是同步的方法,虚拟DOM渲染也是需要时间的,        * 因为console是实时刷新的,还未等setState执行完毕(还未渲染完成)就将结果输出,        * 因此打印的是上一次渲染后的结果。        *        * */    }react通过回调函数的形式,帮我们解决了上面这种情况
          addList() {        this.setState({                                                ......            },            /* 通过回调函数的形式,就可以将结果进行同步 */            () => {                console.log(this.ul.querySelectorAll('li').length)            })10、react生命周期函数

      参考链接:[详解react v16.0前的生命周期][https://www.jianshu.com/p/514fe21b9914]

      1)什么是生命周期函数?

      在某一时刻,可以自动执行的函数。
      2)四个阶段

      1、初始化:Initialization

      constructor
      class Xiaojiejie extends Component {    constructor(props) {        super(props);        this.state = {            //数据驱动,那就在这里填入数据            inputValue: "Ryan",            list: ["基础按摩", "精油推背", "全身按摩"]            // 数据初始化完毕        }    }constructor看起来完全是符合生命周期的,但是,它并不是react独有的,而是ES6的一种语法,所以严格意义上来讲,constructor不属于生命周期,而是属于ES6语法。
      我们可以把constructor当做初始化语法,
      render
          render() {        return ()    }2、挂载:Mounting

      render属于渲染,完全是自动执行的,完全就是一个生命周期函数。
      componentWillMount

      属于DOM挂载之前执行的
      render
      state或props的状态或属性发生改变,才进行一个渲染。
      componentDidMount

      DOM挂载完毕后执行函数。
      componentWillMount ——>> render ——>> componentDidMount3、更新:Updation

      shouldComponentUpdate

      在组件更新之前会自动执行。
          shouldComponentUpdate(nextProps, nextState, nextContext) {        console.log("1、shouldComponentUpdate")        return true    }当我们在输入框开始输入的时候,可以看到console就会有输出。
      发现,shouldComponentUpdate是在render执行之前之前运行的
      shouldComponentUpdate函数需要返回一个布尔类型的值


      • 返回true:继续渲染,执行render函数
      • 返回false:shouldComponentUpdate函数执行,render函数不再执行

      UNSAFE_componentWillUpdate

      UNSAFE_componentWillUpdate:在shouldComponentUpdate之后执行,如果shouldComponentUpdate返回false,那么UNSAFE_componentWillUpdate也不会执行。
      同样,这个函数也是在render之前执行。
      componentDidUpdate

      在render渲染成功后执行。
      UNSAFE_componentWillReceiveProps

      这是props独有的,states中没有这个函数。
      该组件不能放在顶层组件中(Xiaojiejie.js),放在其中,不会执行。因为在子组件中,我们已经接收了props这个属性,所以我们可以去子组件中去操作。
      该组件必须满足两个条件:


      • 组件第一次存在于虚拟DOM中,函数是不会被执行的
      • 如果已经存在于DOM中,函数才会被执行

      4、Unmounting

      在去除或删除的时候使用
      componentWillUnmount

      当组件被删除时自动执行。
      11、性能优化

      我们之前编写的这个demo,存在一定的性能问题。
      在我们的子组件中,添加这样一句代码,然后到浏览器控制台中查看。
      render() {    console.log("child---->>render")  ......}可以看到,每输入一个字母,页面就渲染一次。
      1)如何优化?

      在子组件中添加在前面生命周期函数讲解中所用到的一个函数:
      shouldComponentUpdate(nextProps, nextState, nextContext) {    return false}使用该函数并返回一个false,但是直接这样写也是有问题的,如果是修改的话,就会出错。在该函数中提供了几个参数来为我们解决这个问题。


      • nextProps:接下来要改变的属性
      • nextState:接下来要改变的状态

      当nextProps.content与我们this.props.content不想等的时候,说明content发生了变化(被修改),那我们就需要对页面(render)进行渲染。
      shouldComponentUpdate(nextProps, nextState, nextContext) {    return nextProps.content !== this.props.content;}
      举报

    更多回帖

    发帖
    ×
    20
    完善资料,
    赚取积分