• React interrelated reference Manual


    React 本教程描述一些基本概念

    如果需要入门学习,推荐教程: https://reactjs.org/
    本教程为了加强记忆,更改了学习的顺序。 且会收集教程以外实例。

    React实现了与浏览器无关的DOM系统,以实现性能和跨浏览器的兼容性。

    0. 知识

    0.1,ES6 箭头函数 :

    graph LR A[箭头函数] -- 没有将自己绑定到 --> B((关键词)) B --> C(arguments) B --> D{super} B --> E{new.target} B --> F{this}

    箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

    // 实例应用
    const materials = [
      'Hydrogen',
      'Helium',
      'Lithium',
      'Beryllium'
    ];
    

    巧妙的完成了数组长度的调用;

    console.log(materials.map(material => material.length));
    // expected output: Array [8, 6, 7, 9]
    
    • params => ({foo: bar}) 加括号的函数体返回对象字面量表达式:
    • (param1, param2, ...rest) => { statements } 【and】(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
      statements }
      支持剩余参数默认参数。如例(剩余参数):
    function sum(...theArgs) {
      return theArgs.reduce((previous, current) => {
        return previous + current;
      });
    }
    
    console.log(sum(1, 2, 3));
    // expected output: 6
    
    console.log(sum(1, 2, 3, 4));
    // expected output: 10
    
    • () => { statements } 没有参数的函数应该写成一对圆括号。
    • singleParam => { statements } 当只有一个参数时,圆括号是可选的。
    • 同样支持参数列表解构
      什么是解构?解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。
    let a, b, rest;
    [a, b] = [10, 20];
    
    console.log(a);
    // expected output: 10
    
    console.log(b);
    // expected output: 20
    
    [a, b, ...rest] = [10, 20, 30, 40, 50];
    
    console.log(rest);
    // expected output: Array [30,40,50]
    
    // ---
    let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
    f();  
    // expected output:  6
    

    0.2,进阶指南

    相关知识:

    1. Component API && Component

    • react versions 使用前明确环境与使用的版本。
    • 组件类 API参考:

    Props

    state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。

    function HelloMessage(props) {
        return <h1>Hello {props.name}!</h1>;
    }
    const element = <HelloMessage name="Runoob"/>;
    ReactDOM.render(
        element,
        document.getElementById('example')
    );
    

    关于组件生命周期

    每个组件都有几个“生命周期方法”,您可以重写它们以在流程中的特定时间运行代码。可以参考的生命周期图。

    • 安装时
      • static getDerivedStateFromProps() ; 在初始安装和后续更新上,调用render方法之前立即调用。
      • constructor()
        通常,在React中,constructor构造函数仅用于两个目的:
        1.通过将对象分配给来初始化本地状态this.state。
        2.将事件处理程序方法绑定到实例。
      • render()
        该render()方法是类组件中唯一需要的方法。
        调用时,它应该检查this.props并this.state返回以下类型之一:
        - React elements 元素
        - Arrays and fragments.。从渲染返回多个元素。
        - Portals. 将子级渲染到另一个DOM子树中。
        - String and numbers 字符串和数字。
        - Booleans or null 布尔值或null.
        该render()函数应该是纯函数,这意味着它不会修改组件状态,它在每次调用时都返回相同的结果,并且不与浏览器直接交互。
        如果您需要与浏览器进行交互,请改为使用componentDidMount()或其他生命周期方法执行工作。保持render()纯净使组件更容易考虑。
      • componentDidMount() ; 挂载组件(插入树中)后立即调用。需要DOM节点的初始化应在此处进行。
    • 更新时
      - static getDerivedStateFromProps()
      - shouldComponentUpdate(nextProps, nextState); 当接收到新的Props或State 时,在渲染之前调用。默认为true。
      - render()
      - componentDidUpdate(prevProps, prevState, snapshot); 更新发生后立即调用。初始渲染不调用此方法。
      - getSnapshotBeforeUpdate()
    • 卸载时
      - componentWillUnmount()
    • 错误处理
      可在其子组件树中的任何位置捕获JavaScript错误,记录这些错误并显示后备UI,而不是崩溃的组件树。错误边界会在渲染过程中,生命周期方法中及其下的整个树的构造函数中捕获错误。
      - static getDerivedStateFromError()
      后代组件引发错误后,将调用此生命周期。它接收作为参数抛出的错误,并且应返回值以更新状态。
      - componentDidCatch()
      后代组件引发错误后,将调用此生命周期。它接收两个参数:
      - error -引发的错误。
      - info-具有componentStack密钥的对象,其中包含有关哪个组件引发了错误的信息。
      componentDidCatch()在“提交”阶段调用,因此允许出现副作用。它应用于记录错误之类的事情:
    • 其它API :

       - setState()
       - forceUpdate()
      
    • 类属性
      - defaultProps
      - displayName
    • 实例属性
      - props
      - state

    2. 元素渲染

    <div id="root"></div>
    const element = <h1>Hello, world</h1>;
    ReactDOM.render(element, document.getElementById('root'));
    

    在CodePen上尝试

    它在页面上显示“ Hello,world”。
    

    3. JSX

    import React from 'react';
    import React from 'react';
    
    // Correct! This is a component and should be capitalized:
    function Hello(props) {
    // Correct! This use of <div> is legitimate because div is a valid HTML tag:
    return <div>Hello {props.toWhat}</div>;
    }
    
    function HelloWorld() {
     // Correct! React knows <Hello /> is a component because it's capitalized.
    return <Hello toWhat="World" />;
    }
    

    与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。
    要将 React 元素渲染到根 DOM 节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:

    const element = < HelloWorld />;
    ReactDOM.render(element, document.getElementById('example'));  
    

    4,This && 事件处理 Handling Events

    必须谨慎对待 JSX 回调函数中的 this,在 JavaScript 中,class 的方法默认不会绑定 this。如果你忘记绑定 this.handleClick 并把它传入了 onClick,当你调用这个函数的时候 this 的值为 undefined。

    HTML
        <button onclick="activateLasers()">
           Activate Lasers
         </button>
    
    在React中略有不同:
        <button onClick={activateLasers}>
          Activate Lasers
        </button>
    

    使用React时,通常不需要addEventListener在创建DOM元素后调用将侦听器添加到DOM元素。相反,仅在最初呈现元素时提供一个侦听器。

    此Toggle组件呈现一个按钮,该按钮使用户可以在“ ON”和“ OFF”状态之间切换:
    class Toggle extends React.Component {
    
       constructor(props)
        {
       //子类 必须 在 constructor( )调用 super( )方法,否则新建实例时会报错。
       // 报错的原因是:子类是没有自己的 this 对象的,它只能继承自父类的 this 对象,然后对其进行加工,而super( )就是将父类中的this对象继承给子类的。没有 super,子类就得不到 this 对象。
       //无论有没有constructor,在render中this.props都是可以使用的,这是React自动附带的; 
          super(props);
          this.state = {isToggleOn: true};
    // 这种绑定是使`this`在回调中起作用所必需的
          this.handleClick = this.handleClick.bind(this);  
       }
    
       handleClick() {    
           this.setState(state => ({ isToggleOn: !state.isToggleOn }));
        }
    
       render() {
           return (
                <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : 'OFF'}
               </button>
            );
        }
    
    }
        
    ReactDOM.render(
          <Toggle />,
          document.getElementById('root')
    );
    

    5.React 条件渲染 && React 列表 & Keys

    条件

    function Greeting(props) {
    const isLoggedIn = props.isLoggedIn;
    if (isLoggedIn) {
    return <UserGreeting />;
    }
    return <GuestGreeting />;
    }
     ReactDOM.render(
    // Try changing to isLoggedIn={true}:
    <Greeting isLoggedIn={false} />,
    document.getElementById('root')
    );
    

    列表

    function NumberList(props) {
    const numbers = props.numbers;
    const listItems = numbers.map((number) =>
    <li>{number}</li>
    );
    return (
    <ul>{listItems}</ul>
    );
    }
    
    const numbers = [1, 2, 3, 4, 5];
    ReactDOM.render(
    <NumberList numbers={numbers} />,
    document.getElementById('root')
    );
    

    6. Hook( 挂钩 )&& React State(状态)

    简介

    Hook 是React 16.8中的新增功能。它们使您无需编写类即可使用 State 和其他React功能。
    import React, { useState } from 'react';

    function Example() {
      // Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    

    Hooks 钩子 解决了React在我们看来的各种的问题。无论您是学习React,每天使用它,还是偏爱具有相似组件模型的其他库,您都可能会意识到以下的一些问题。

    • 很难在组件之间重用状态逻辑
    • 复杂的组件变得难以理解
    • 类会使人和机器混淆
      至关重要的是,Hooks与现有代码并存,因此您可以逐渐采用它们。

    如果想探索更多Hook的动机,可以详细参考(RFC)

    钩子一览

    建立自己的挂钩

    有时,我们想在组件之间重用一些状态逻辑。传统上,有两种流行的解决方案:Higher-Order Components 和 Render Props。使用自定义钩子可以执行此操作,但无需在树中添加更多组件
    import React, { useState, useEffect } from 'react';

    function useFriendStatus(friendID) { 
    const [isOnline, setIsOnline] = useState(null);
    function handleStatusChange(status) {
        setIsOnline(status.isOnline);
      }
    
      useEffect(() => {
        ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
        return () => {
          ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
        };
      });
    
      return isOnline;
    }
    // 它friendID 作为参数,并返回我们的朋友是否在线。现在我们可以在两个组件中使用它:
    //
    function FriendStatus(props) {
      const isOnline = useFriendStatus(props.friend.id);
      if (isOnline === null) {
        return 'Loading...';
      }
      return isOnline ? 'Online' : 'Offline';
    }
    //
    function FriendListItem(props) {
      const isOnline = useFriendStatus(props.friend.id);
      return (
        <li style={{ color: isOnline ? 'green' : 'black' }}>
          {props.friend.name}
        </li>
      );
    }
    

    这些组件的状态是完全独立的。挂钩是重用有状态逻辑而不是状态本身的一种方法。实际上,每个对Hook的调用都具有完全隔离的状态-因此,您甚至可以在一个组件中使用同一自定义Hook两次。

    自定义钩子更多的是约定俗成的功能。如果函数的名称以“ use” 开头并且调用了其他挂钩,则我们将其称为自定义挂钩。该useSomething命名约定是我们的棉短绒插件如何能够找到使用钩在代码中的bug。

    您可以编写自定义的Hook,这些自定义的Hook涵盖了各种用例,例如表单处理,动画,声明式订阅,计时器,以及可能还没有考虑的更多用例。

    State Hook
    import React, { useState } from 'react';
    
    function Example() {
      // Declare a new state variable, which we'll call "count"  
    const [count, setCount] = useState(0);
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    // 等效类的示例
    class Example extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          count: 0
        };
      }
    
      render() {
        return (
          <div>
            <p>You clicked {this.state.count} times</p>
            <button onClick={() => this.setState({ count: this.state.count + 1 })}>
              Click me
            </button>
          </div>
        );
      }
    }
    
    Effect Hook

    如果你熟悉阵营类生命周期方法,你能想到的useEffect钩。因为componentDidMount,componentDidUpdate和componentWillUnmount结合。
    import React, { useState, useEffect } from 'react';
    function Example() {
    const [count, setCount] = useState(0);

      // Similar to componentDidMount and componentDidUpdate:  
    useEffect(() => {  
    // Update the document title using the browser API 
     document.title = `You clicked ${count} times`;  });
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    钩子规则:挂钩是JavaScript函数,但是它们施加了两个附加规则
    • 仅在顶层调用Hooks。

    不要在循环,条件或嵌套函数中调用Hook。请始终在您的React函数的顶层使用挂钩。通过遵循此规则,可以确保每次渲染组件时都以相同的顺序调用Hook。

    • 仅从React函数组件调用Hook 。

    不要从常规的JavaScript函数中调用Hook。React从React函数组件中调用Hook。可以从自定义挂钩中调用挂钩 。

    我们提供了一个linter插件来自动执行这些规则。我们知道这些规则乍看起来似乎是局限性的或令人困惑的,但是它们对于使Hooks正常工作至关重要。

    Hooks API参考

    常用

  • 相关阅读:
    codeforces 671B Robin Hood 二分
    HDU 4009 Transfer water 最小树形图
    HDU 2121 Ice_cream’s world II 最小树形图
    UVA1395 Slim Span(枚举最小生成树)
    ZOJ 1107FatMouse and Cheese(BFS)
    POJ2239 Selecting Courses(二分图最大匹配)
    UVA 11419SAM I AM(输出 最小覆盖点 )
    POJ 3678 Katu Puzzle(强连通 法)
    POJ3207Ikki's Story IV
    POJ1236Network of Schools(强连通分量 + 缩点)
  • 原文地址:https://www.cnblogs.com/q1104460935/p/12844952.html
Copyright © 2020-2023  润新知