• React基础学习


    JSX

    为了便于阅读,建议将jsx拆分为多行,并且将内容用()包裹,这可以避免遇到自动插入分号陷阱。

    注:自动插入分号ASI(auto semicon insertion)

    (回车符), (换行符), 的区别

    在以 ([/+- 开头的语句前加分号

    尤大解读

    React DOM 使用 camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。class 变为className , tabindex 变为tabIndex。

    JSX可以防止 XSS(cross-site-scripting, 跨站脚本)攻击。

    Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。

    以下两种代码完全等效:

    const element = (
      <h1 className="greeting">
        Hello, world!
      </h1>
    );
    
    const element = React.createElement(
      'h1',
      {className: 'greeting'},
      'Hello, world!'
    );
    

    元素渲染

    想要将一个元素渲染到跟DOM节点中,只需把它们一起传入 ReactDOM.render()

    React 元素是不可变对象

    考虑 UI 在任意给定时刻的状态,而不是随时间变化的过程,能够消灭一整类的 bug。

    组件&Props

    React 元素也可以是用户自定义的组件

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

    从组件自身的角度命名 props,而不是依赖于调用组件的上下文命名。

    所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。

    纯函数:不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果。

    function sum(a, b) {
      return a + b;
    }
    

    State & 生命周期

    react class方式声明:

    1. 先调用constructor初始化state
    2. 调用render函数渲染DOM元素
    3. 调用相关生命周期方法

    当State中的某个状态发生变化,我们应该重新创建这个状态对象,而不是直接修改原来的状态。

    正确渲染state:

    1. 调用setState()方法来更新state的状态,且构造函数是唯一可以给this.state赋值的地方

    2. state的更新可能是异步的

      出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。

      this.setState(function(state, props) {
        return {
          counter: state.counter + props.increment
        };
      });
      
    3. 当你调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。组件State的更新是一个浅合并的过程。

    深入React组件状态

    任何的 state 总是所属于特定的组件,而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件。

    事件处理

    • React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
    • 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。

    如果需要组织事件的默认行为,必须显式的调用 preventDefault

    引出

    事件委托

    事件循环机制

    MutationObserver

    宏任务和微任务

    堆栈

    javascript bind()

    绑定事件处理函数作用域的方式

    • 利用bind方法

      constructor(props) {
          super(props);
          this.state = {isToggleOn: true};
      
          // 为了在回调中使用 `this`,这个绑定是必不可少的
          this.handleClick = this.handleClick.bind(this);
        }
      
    • 你可以在回调中使用箭头函数,不推荐,每次会创建一个新的函数,当做参数传入子组件,可能会进行额外的重新渲染

         // 此语法确保 `handleClick` 内的 `this` 已被绑定。
      render() {
          return (
            <button onClick={(e) => this.handleClick(e)}>
              Click me
            </button>
          );
        }
      
    • class fields 语法

      // 此语法确保 `handleClick` 内的 `this` 已被绑定。
        // 注意: 这是 *实验性* 语法。
        handleClick = () => {
          console.log('this is:', this);
        }
      

    向事件处理程序传递参数

    <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
    <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
    

    使用箭头函数绑定事件时,需要显示传递事件对象e

    条件渲染

    与运算符 &&

    return (
        <div>
          <h1>Hello!</h1>
          {unreadMessages.length > 0 &&
            <h2>
              You have {unreadMessages.length} unread messages.
            </h2>
          }
        </div>
      );
    

    在 JavaScript 中,true && expression 总是会返回 expression, 而 false && expression 总是会返回 false

    在极少数情况下,你可能希望能隐藏组件,即使它已经被其他组件渲染。若要完成此操作,你可以让 render 方法直接返回 null,而不进行任何渲染。

    function WarningBanner(props) {
      if (!props.warn) {
        return null;
      }
    
      return (
        <div className="warning">
          Warning!
        </div>
      );
    }
    

    在组件的 render 方法中返回 null 并不会影响组件的生命周期。

    列表 & Key

    key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。

    给数组元素赋予确定标识的方式

    • 使用元素的id

    • 使用索引index。如果你选择不指定显式的 key 值,那么 React 将默认使用索引用作为列表项目的 key 值。如果列表项目的顺序可能会变化,我们不建议使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。example

      const todoItems = todos.map((todo, index) =>
        // Only do this if items have no stable IDs
        <li key={index}>
          {todo.text}
        </li>
      );
      

    元素的 key 只有放在就近的数组上下文中才有意义。即放在数组元素上,不论数组元素是原生标签还是自定义组件。

    这个 key 不需要全局唯一,但在列表中需要保持唯一。

    key 会传递信息给 React ,但不会传递给你的组件。如果你的组件中需要使用 key 属性的值,请用其他属性名显式传递这个值:

    const content = posts.map((post) =>
      <Post
        key={post.id}
        id={post.id}
        title={post.title} />
    );
    

    如果一个 map() 嵌套了太多层级,那可能就是你提取组件的一个好时机。

    引出

    算法时间复杂度 算法复杂度分析

    React 在以下两个假设的基础之上提出了一套 O(n) 的启发式算法:

    1. 两个不同类型的元素会产生出不同的树;
    2. 开发者可以通过 key prop 来暗示哪些子元素在不同的渲染下能保持稳定;

    Diffing算法

    react diff算法 react diff算法源码分析

    react tree diff 在处理层级移动时,会重新创建整个层级,影响性能。可以使用CSS显示或隐藏节点,而不是真的添加和删除节点。

    在开发过程中,尽量减少类似将最后一个节点移动到列表首部的操作,当节点数量过大或更新操作过于频繁时,在一定程度上会影响 React 的渲染性能。

    表单

    当需要处理多个 input 元素时,我们可以给每个元素添加 name 属性,并让处理函数根据 event.target.name 的值选择要执行的操作。

    受控组件上指定 value 的 prop 可以防止用户更改输入。如果指定了 value,但输入仍可编辑,则可能是意外地将value 设置为 undefinednull

    react表单组件

    受控组件

    • 设置value/checked属性
    • 设置onChange事件

    非受控组件

    • 默认值通过defaultValue来进行设置
    • 使用 ref 来从 DOM 节点中获取表单数据

    在 React 中,<input type="file" /> 始终是一个非受控组件,因为它的值只能由用户设置,而不能通过代码控制。

    引出

    使用受控组件的条件

    • 就地反馈,如表单即时验证
    • 除非所有的字段都有效,否则禁用提交按钮
    • 强制执行特定的输入格式,如信用卡号码

    如何选用受控组件和非受控组件

    refs

    • ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。
    • ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。
    • 你不能在函数组件上使用 ref 属性,因为他们没有实例。你可以在函数组件内部使用 ref 属性,只要它指向一个 DOM 元素或 class 组件

    Ref 转发使组件可以像暴露自己的 ref 一样暴露子组件的 ref

    回调方式

    • 构造器中声明一个变量,在组件挂载完成后,调用生命周期方法,赋予这个变量对应的元素

    通过React.createRef()方式创建

    • 当 ref 被传递给 render 中的元素时,对该节点的引用可以在 ref 的 current 属性中被访问。
    • 通过在ref组件中调用 React.forwardRef()API实现ref的转发 ref传递

    状态提升

    你应当依靠自上而下的数据流,而不是尝试在不同组件间同步 state。

    虽然提升 state 方式比双向绑定方式需要编写更多的“样板”代码,但带来的好处是,排查和隔离 bug 所需的工作量将会变少。

    如果某些数据可以由 props 或 state 推导得出,那么它就不应该存在于 state 中。

    React 开发者工具

    组合 vs 继承

    特殊prop属性children ,类似于Vue中的插槽

    实现具名插槽

    function SplitPane(props) {
      return (
        <div className="SplitPane">
          <div className="SplitPane-left">
            {props.left}
          </div>
          <div className="SplitPane-right">
            {props.right}
          </div>
        </div>
      );
    }
    
    function App() {
      return (
        <SplitPane
          left={
            <Contacts />
          }
          right={
            <Chat />
          } />
      );
    }
    

    常用于组件复用UI功能

    对于非UI功能的复用,组件可以直接引入(import)而无需通过 extend 继承它们。

  • 相关阅读:
    1002CSP-S模拟测试赛后总结
    「题解」:X国的军队
    1001CSP-S模拟测试赛后总结
    「题解」:联
    0929CSP-S模拟测试赛后总结
    「题解」:Kill
    「题解」:y
    Censoring【自动AC机】【水题毁我青春】【20190614】
    传说级快读
    针对值域与下标关系的总结
  • 原文地址:https://www.cnblogs.com/goOtter/p/10955399.html
Copyright © 2020-2023  润新知