• react 教程—核心概念


    react 核心概念  : https://react.docschina.org/docs/getting-started.html(官网) 或  https://www.w3cschool.cn/react/react-tutorial.html


     一、react 的 JSX:

      1、概念: react 本质上是js,但是react自己用创造了一个表达式,即JSX表达式。(可以理解为,react中的js经过react编译为真正的js。原生的js就不变,像JSX这种react的语法就编译成原生的js)

      官方上把 JSX 语法称为 表达式,个人觉得也可以把 JSX 称为一种 数据类型 。类似正则表达式,等号右边只有一个 正则字面量(表达式可以是只有这个字面量的,https://www.cnblogs.com/fangsmile/p/8337021.html)。

      如下面的 JSX 语法:等号右边只有一个类似字面量的值,就叫 JSX字面量好了(类比正则字面量)。

    const element = <h1>Hello, world!</h1>;    // 等号右边的这个表达式,原生js是会报错的,无法识别。但是react 的可以识别的。

      JSX 的基本语法规则 :遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。 http://www.ruanyifeng.com/blog/2015/03/react.html

      注意:JSX 语法不是 JS 引擎 解析的,所以不要完全使用js的语法规则去分析 JSX 代码。JSX 编译后的代码才是 js 代码。

         JSX 表达式最外层只能有一个标签,这点 和 vue 是一样的。

      2、JSX表达式外面的括号:JSX 标签里能够包含很多子元素,前后要加上括号。如:

    const element = <img src={user.avatarUrl} />;   // img标签内没有其他的子元素,可以不用括号
    const element = (
      <div>                  // div 标签里有子元素
        <h1>Hello!</h1>
        <h2>Good to see you here.</h2>
      </div>
    );

      3、JSX表达式,经过 babel转译,所有的JSX表达式会变成调用 React 的 createElement 方法,变成如下代码。(JSX编译后的代码用到了React对象,所以必须要引入React对象)

    import React, { Component } from 'react';
    
    class Process extends Component {
      render() {
        return (<div>哈哈哈</div>)
      }
    }
    
    /*  babel 编译后 */
    import React, { Component } from 'react';
    
    class Process extends Component {
      render() {
        return React.createElement(
          'div',
          null,
          'u54C8u54C8u54C8'
        );
      }
    }

    二、react元素渲染:https://react-1251415695.cos-website.ap-chengdu.myqcloud.com/docs/rendering-elements.html (一个 JSX 表达式 就是一个 react元素)

       react 元素 渲染 是通过 ReactDOM.render()方法进行渲染的,将 react元素 和 挂载的 DOM对象,作为参数传递给这个方法就了。如:

    const element = <h1>Hello, world</h1>;   // react 元素
    ReactDOM.render(element, document.getElementById('root'));

    三、react组件:https://react-1251415695.cos-website.ap-chengdu.myqcloud.com/docs/components-and-props.html  或  https://www.jianshu.com/p/f5c9ec0917bb(React创建组件的三种方法)

       定义组件的三种方法: 函数组件与 class 组件(创建后两个组件在 React 里是等效的,class组件有他的额外特性)

        1、函数组件:(函数组件,本质上是一个函数。相比较 类组件,函数组件有很多东西是没有的。)       开始使用react,不清楚什么时候使用函数组件好。就全部使用class组件吧。

    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }

        2、React.Component组件:以ES6的形式来创建react的组件的(React目前极为推荐的创建有状态组件的方式,https://www.jianshu.com/p/f5c9ec0917bb

    class Welcome extends React.Component {
      render() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    }

        3、React.createClass 组件:以 ES5的原生的JavaScript来实现的React组件。【这个基本和class的一样,现在开发基本 不予考虑,16.0版本已经抛弃了React.createClass方法

    var HelloMessage = React.createClass({
      render: function() {
        return <h1>Hello {this.props.name}</h1>;
      }
    });
    
    ReactDOM.render(
      <HelloMessage name="fannieGirl" />,
      document.getElementById('example')
    );

    注意: 组件名称必须以大写字母开头。

    总结:1、react 组件的本质是函数 返回一个JSX 表达式(react元素)。class组件也是一样,在内部 render 方法中,返回一个JSX 表达式。

       2、函数组件和类组件的区别。          参考    https://blog.csdn.net/wu_xianqiang/article/details/91320529

          函数组件  的性能比  类组件  的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件

    区别函数组件类组件
    是否有 this 没有
    是否有生命周期 没有
    是否有状态 state 没有

          3、需要使用到state的地方就必须要使用类组件。一般当前组件,调用ajxa请求数据,都好用到state

    四、react元素 渲染:react组件要渲染成 DOM,需要先将组件变成 react元素(把组件当标签使用就可以变成react元素),再使用react元素的渲染方法进行渲染。如:

    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }
    
    const element = <Welcome name="Sara" />;   //Welcome组件 当标签使用就可以变成react元素了
    ReactDOM.render( element, document.getElementById(
    'root') );

    五、Props:父组件传递给子组件的数据。  

      1、Props 的只读性:组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。

    this.props.name    //class组件中获取父组件传递过来的值,函数组件中去掉 this

      2、很多文章介绍,props改变,会重新渲染子组件。这个其实是错误的,props 修改不会,引起子组件的如何变化,只是父组件中某个变量的值改变了。

        往往 props 的值 是state值传递过来的。修改这个state 才导致,父组件 调用 render 方法,递归更新所有的组件树。这个时候新的props才传递进去的。

    六、State:react组件的状态 ,state状态一旦改变就会调用  组件的 render 方法,重新生成虚拟DOM树,通过diff比较,更新视图(虚拟DOM本身的更新,对ui没有任何的影响,只有挂载到真实DOM上才是有效的)。

       理解:state 中的属性的数据变化,与其他的变量的主要区别是,state的变化会驱动 ui 重新渲染的

      this.state.name  // 读取 state 内的属性值
      this.setState({   // 这个方法就是修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件
          name:'dd'
      })
       

      1、设置state使用setState方法,setState方法 可能是一个异步方法(不能保证 同步执行,大部分情况是同步执行的。开发还是把它 当成异步处理,这个可以避免错误),

        一个生命周期内所有的 setState 方法会合并操作。所以不会改变一个state数据就更新下 ui组件,一次性把state都设置好,在更新ui组件。

      2、this.setState 修改某一对象的某个属性值: 其它属性保留不变:https://blog.csdn.net/Wcharles666/article/details/90269837  或 https://yq.aliyun.com/articles/667986(推荐,提供了3钟方法)

            let paginationParam = Object.assign({}, this.state.paginationParam, {current: 1})  // 这里用到 Object.assign 将所有可枚举属性的值从一个或多个源对象复制到目标对象
            this.setState({
              paginationParam:paginationParam
            })

    七、React 组件生命周期:       详细介绍,在另外一篇文章上有写    https://www.cnblogs.com/wfblog/p/11842622.html(说明了各个生命周期执行的顺序)

      a、componentWillMount:

      b、componentDidMount : 在第一次渲染后调用,之后组件已经生成了对应的DOM结构。

      c、componentWillReceiveProps :在组件接收到一个新的prop时被调用

      d、shouldComponentUpdate :

      e、componentWillUpdate:在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

      f、componentDidUpdate :在组件完成更新后立即调用。在初始化时不会被调用。

      g、componentWillUnmount:在组件从 DOM 中移除的时候立刻被调用。

    八、事件处理:https://react.docschina.org/docs/handling-events.html

    <button onClick={activateLasers}>
      Activate Lasers
    </button>

      1、react中不能通过返回 false 的方式阻止默认行为。你必须显式的使用 preventDefault 

      2、JSX表达式中DOM元素绑定的事件,需要手动绑定 this,不然 事件函数中使用this会报错。https://www.cnblogs.com/yuyujuan/p/10111164.html

        绑定的方法:

        a、通过bind来指明当前方法中的this指向当前Home.js组件

    render() {
    // 通过bind方法实现,可以传递参数
    return <button onClick={this.handleClick.bind(this, 'test')}>Test</button>;
    }

        b、在构造函数constructor中改变this指向。

    class App extends Component {
        constructor(props) {
            super(props);
            this.handleClick = this.handleClick.bind(this);
        }
        handleClick(e) {
            console.log(e);
        }
        render() {
            return <button onClick={this.handleClick}>Test</button>;
        }
    }    

        c、使用箭头函数改变this指向。

    render() {
        return <button onClick={() => this.handleClick()}>Test</button>
    }

      3、事件函数中 带自定义的参数:

        上面的 3种 绑定 this 的事件函数方法中,其中第二种是无法 传入自定义参数的。但是可以把需要的参数,作为这个DOM对象的属性放上去。

    class Alphabet extends React.Component {
      handleClick(e) {
        this.setState({
          justClicked: e.target.dataset.letter  // 这里通过 获取DOM的自定义属性,获取了事件函数 需要的参数
        });
      }
     
      render() {
        return (
                <div data-letter={letter} onClick={this.handleClick}>
                  {letter}
                </div>
        )
      }
    }

    九、 条件渲染:    https://react.docschina.org/docs/conditional-rendering.html

      条件渲染的方式:

      1、react的条件渲染是 ,通过再创建一个组件组件,这个组件中通过js的条件判断返回不同的组件。                                             https://react.docschina.org/docs/conditional-rendering.html

    function UserGreeting(props) {
      return <h1>Welcome back!</h1>;
    }
    
    function GuestGreeting(props) {
      return <h1>Please sign up.</h1>;
    }
    
    function Greeting(props) {  // 这个就是另外创建的组件
      const isLoggedIn = props.isLoggedIn;
      if (isLoggedIn) {
        return <UserGreeting />;
      }
      return <GuestGreeting />;
    }

      2、JSX 花括号中,使用   运算符 &&  。            这个方法只能  相当于 if 的功能,不能作为  if...else...  的功能。

    function Mailbox(props) {
      const unreadMessages = props.unreadMessages;
      return (
        <div>
             {unreadMessages.length > 0 && (<h2>hello</h2>)}
        </div>
      );
    }

      3、JSX 花括号中,使用   三目运算符                 condition ? true : false

    render() {
      const isLoggedIn = this.state.isLoggedIn;
      return (
        <div>
          {isLoggedIn ? (
            <LogoutButton onClick={this.handleLogoutClick} />
          ) : (
            <LoginButton onClick={this.handleLoginClick} />
          )}
        </div>
      );
    }

      重点:JSX表达式中花括号也是可以使用JSX元素的(把JSX元素当成一个数据,就像字符串)

    十、列表 渲染 :https://react.docschina.org/docs/lists-and-keys.html

      1、通过map渲染              (JSX表达式中,如果花括号只有一个数组,则react编译时,会把所有的项拼接在一起)

     const numbers = [1, 2, 3, 4, 5];
     const listItems = numbers.map((number,index) =>
          <li key={index}>{number}</li>
      );
     return(  
          <div>
            {listItems}     // 这里 listItems 是一个数组,react编译后,会把这个数组中的每项拼接在一个
          </div>
        )
      }

      注意:列表渲染的标签必须有一个 key 属性,这点 和 VUE 是一样的原理。    官网上说,不建议使用   索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。

    十一、表单:https://react.docschina.org/docs/forms.html

      1、受控组件:表单的数据保存在组件的 state 属性中,并且只能通过使用 setState()来更新。从效果来看的话,受控组件 实现了 双向绑定的功能。

              受控组件,如果没有绑定 Change 事件,通过setState()来更新,则输入不了内容。不同的 表单元素,select 、textarea  怎么处理看上面网站

    class NameForm extends React.Component {
      state = {value: ''};
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      render() {
        return (
           <input type="text" value={this.state.value} onChange={this.handleChange.bind(this)} />
        );
      }
    }

        a、多个受控组件,给每一个表单设置一个 onChange 事件函数,这种处理方式肯定会导致代码不好维护。处理方式是:        https://blog.csdn.net/weixin_30371875/article/details/98777554

      handleChange(val,event){
          this.inputData[val] = event.target.value  
      }
     <input onChange={this.handleChange.bind(this, 'gtPersonNum')}/> 
     <input onChange={this.handleChange.bind(this, 'ltPersonNum')}/> 

    2、非受控组件:和 以前 html 的差不多的使用, 使用 ref  指向 这个表单对象。下面的,this.input 表示的就是这个input表单。

    class NameForm extends React.Component {
      constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.input = React.createRef();
      }
    
      handleSubmit(event) {
        alert(this.input.current.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
              <input type="text" ref={this.input} />   // this.input 指向当前的DOM节点
          </form>
        );
      }
    }

      test(){
         console.log(this.input.value); 这里直接使用DOM节点的方法,获取节点数据
      }
      render() {
         return (
            <input type="text" ref={(input) => this.input = input} 
      onChange={this.test.bind(this)}/>  // 这里 把 this.input 指向当前DOM 节点
          )
      }
  • 相关阅读:
    leetcode1030之距离顺序排列矩阵单元格
    leetcode56之合并区间
    leetcode976之三角形最大周长
    leetcode922----按奇偶排序数组
    leetcode198之打家劫舍问题
    leetcode350之实现求解两数组交集(包含重复元素)
    【Python错误】日常记录(持续更新)
    【JavaScript】Lodash在React Native中的使用
    【Python】BeautifulSoup的使用
    转载【Python】python正则表达式详解
  • 原文地址:https://www.cnblogs.com/wfblog/p/9461984.html
Copyright © 2020-2023  润新知