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. 元素渲染


const element =

Hello, world

;
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

is legitimate because div is a valid HTML tag:
return
Hello {props.toWhat}
;
}

function HelloWorld() {
// Correct! React knows is a component because it's capitalized.
return ;
}
与浏览器的 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 ;
}
return ;
}
ReactDOM.render(
// Try changing to isLoggedIn={true}:
,
document.getElementById('root')
);

列表

function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>

  • {number}

  • );
    return (
      {listItems}

    );
    }

    const numbers = [1, 2, 3, 4, 5];
    ReactDOM.render(
    ,
    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 (


    You clicked {count} times


    <button onClick={() => setCount(count + 1)}>
    Click me


    );
    }

    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}

    );
    }
    这些组件的状态是完全独立的。挂钩是重用有状态逻辑而不是状态本身的一种方法。实际上,每个对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 (


    You clicked {count} times


    <button onClick={() => setCount(count + 1)}>
    Click me


    );
    }
    // 等效类的示例
    class Example extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    count: 0
    };
    }

    render() {
    return (


    You clicked {this.state.count} times


    <button onClick={() => this.setState({ count: this.state.count + 1 })}>
    Click me


    );
    }
    }

    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 (


    You clicked {count} times


    <button onClick={() => setCount(count + 1)}>
    Click me


    );
    }

    钩子规则:挂钩是JavaScript函数,但是它们施加了两个附加规则
    • 仅在顶层调用Hooks。

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

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

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

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

    Hooks API参考

    常用

    posted @ 2020-05-07 19:05  徐锅  阅读(315)  评论(0)    收藏  举报