React 备忘清单 === [![NPM version](https://img.shields.io/npm/v/react.svg?style=flat)](https://npmjs.org/package/react) [![Downloads](https://img.shields.io/npm/dm/react.svg?style=flat)](https://www.npmjs.com/package/react) [![Repo Dependents](https://badgen.net/github/dependents-repo/facebook/react)](https://github.com/facebook/react/network/dependents) [![Github repo](https://badgen.net/badge/icon/Github?icon=github&label)](https://github.com/facebook/react) 适合初学者的综合 React 备忘清单 入门 ---- ### 介绍 React 是一个用于构建用户界面的 JavaScript 库 - [React 官方文档](https://reactjs.org/) _(reactjs.org)_ - [Styled Components 备忘清单](./styled-components.md) _(jaywcjlove.github.io)_ - [TypeScript JSX 备忘清单](./typescript.md#jsx) _(jaywcjlove.github.io)_ ```js import {createRoot} from 'react-dom/client' import App from './App' ``` ----- ```jsx const elm = document.getElementById('app') const root = createRoot(elm); root.render(); ``` #### 快速创建 **React** 项目 ([CRA](https://github.com/facebook/create-react-app)) ```shell npx create-react-app my-app ``` ### 导入多个导出 ```jsx import React, {Component} from 'react' import ReactDOM from 'react-dom' ``` ----- ```jsx export class Hello extends Component { ... } export default function World() { /* ... */ } ``` 使用 `export` 导出 **`Hello`**,`export default` 导出 **`World`** 组件 ```jsx import World, { Hello } from './hello.js'; ``` 使用 `import` 导入 `Hello` 组件,在示例中使用。 ### React 组件中的 CSS ```jsx {2,5} import React from "react"; import "./Student.css"; export const Student = (
); ``` 注意:类属性 `className` ```jsx const divStyle = { backgroundImage: 'url(' + imgUrl + ')', }; export const Student = (
); ``` ### 属性 ```jsx ``` 函数组件 `Student` 中访问属性 ```jsx function Student(props) { return

Hello, {props.name}

; } ``` Class 组件 `Student` 中访问属性 ```jsx class Student extends React.Component { render() { return (

Hello, {this.props.name}

); } } ``` `class` 组件使用 `this.props` 访问传递给组件的属性。 ### Children ```jsx function Example() { return (

您有待处理的通知

) } ``` 函数 `AlertBox` 组件 ```jsx {4} function AlertBox(props) { return (
{props.children}
); } ``` ----- ```jsx {props.children} ``` Class `AlertBox` 组件,与函数组件 `AlertBox` 组件相同 ```jsx {5} class AlertBox extends React.Component { render () { return (
{this.props.children}
); } } ``` ----- ```jsx {this.props.children} ``` `children` 作为子组件的的属性传递。 ### State 函数中的 State,Hook 是 React 16.8 的新增特性 ```jsx {4,8} import { useState } from 'react'; function Student() { const [count, setCount] = useState(0); const click = () => setCount(count + 1); return (

您点击了 {count} 次

); } ``` 使用 `setState` 更新状态,下面是函数组件读取状态 ```jsx

您点击了 {count} 次

``` #### Class 中的 State ```jsx {6,12,20} import React from 'react'; class Student extends React.Component { constructor(props) { super(props); this.state = {count: 1}; // 确保函数可以访问组件属性(ES2015) this.click = this.click.bind(this); } click() { const count = this.state.count; this.setState({ count: count + 1}) } render() { return (

您点击了{this.state.count}次

); } } ``` 使用 `setState` 更新状态,`class` 组件中不能使用 ~~hooks~~。下面是 `class` 组件读取状态 ```jsx

您点击了{this.state.count}次

``` ### 循环 ```jsx const elm = ['one', 'two', 'three']; function Student() { return ( ); } ``` `key` 值在兄弟节点之间必须唯一 ### 事件监听 ```jsx export default function Hello() { function handleClick(event) { event.preventDefault(); alert("Hello World"); } return ( Say Hi ); } ``` ### 函数注入 ```jsx function addNumbers(x1, x2) { return x1 + x2; } const element = (
{addNumbers(2, 5)}
); ``` ### 嵌套 ```jsx import { useState } from 'react' import Avatar from './Avatar'; import Profile from './Profile'; function Student() { const [count, setCount] = useState(0); return (
); } ``` ### Portals React 并_没有_创建一个新的 `div`。它只是把子元素渲染到 `domNode` 中。`domNode` 是一个可以在任何位置的有效 DOM 节点。 ```jsx render() { return ReactDOM.createPortal( this.props.children, domNode ); } ``` 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案 ### Fragment ```jsx {1,6,9} import { Fragment } from 'react' import Avatar from './Avatar'; import Profile from './Profile'; const Student = () => ( ); ``` 从 `v16.2.0` 开始 `Fragment` 可用于返回多个子节点,而无需向 DOM 添加额外的包装节点。或者使用 `<>` 效果是一样的。 ```jsx {2,5} const Student = () => ( <> ); ``` 查看: [Fragments & strings](https://reactjs.org/blog/2017/09/26/react-v16.0.html#new-render-return-types-fragments-and-strings) ### 返回字符串 ```jsx {2} render() { return 'Look ma, no spans!'; } ``` 您可以只返回一个字符串。查看: [Fragments & strings](https://reactjs.org/blog/2017/09/26/react-v16.0.html#new-render-return-types-fragments-and-strings) ### 返回数组 ```jsx const Student = () => [
  • First item
  • ,
  • Second item
  • ]; ``` 不要忘记 `key`!查看: [Fragments & strings](https://reactjs.org/blog/2017/09/26/react-v16.0.html#new-render-return-types-fragments-and-strings) ### Refs 转发 ```jsx const FancyButton = React.forwardRef( (props, ref) => ( ) ); ``` #### 使用 ```jsx // 你可以直接获取 DOM button 的 ref: const ref = React.createRef(); 点击我 ; ``` ### Class 组件内部使用 ref 属性 ```jsx {6,10} import {Component,createRef} from 'react' class MyComponent extends Component { constructor(props) { super(props); this.myRef = createRef(); } render() { return
    ; } } ``` 提示:Refs 适用于类组件,但不适用于函数组件(除非您使用 useRef hook,请参阅[hooks](#hooks)) ### 函数组件内部使用 ref 属性 ```jsx {3,9} function CustomTextInput(props) { // 这里必须声明 $input,这样 ref 才可以引用它 const $input = useRef(null); function handleClick() { $input.current.focus(); } return (
    ); } ``` ### 严格模式 StrictMode ```jsx {3,8}
    ``` ----- - [识别不安全的生命周期](https://zh-hans.reactjs.org/docs/strict-mode.html#identifying-unsafe-lifecycles) - [关于使用过时字符串 ref API 的警告](https://zh-hans.reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage) - [关于使用废弃的 findDOMNode 方法的警告](https://zh-hans.reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage) - [检测意外的副作用](https://zh-hans.reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects) - [检测过时的 context API](https://zh-hans.reactjs.org/docs/strict-mode.html#detecting-legacy-context-api) - [确保可复用的状态](https://zh-hans.reactjs.org/docs/strict-mode.html#ensuring-reusable-state) 突出显示应用程序中潜在问题的工具。请参阅:[严格模式](https://zh-hans.reactjs.org/docs/strict-mode.html) ### Profiler 测量一个 React 应用多久渲染一次以及渲染一次的 `代价` ```jsx ``` 为了分析 `Navigation` 组件和它的子代。应该在需要时才去使用它。 :- | :- :- | :- `id(string)` | 发生提交的 `Profiler` 树的 `id` `onRender(function)` | 组件树任何组件 “提交” 一个更新的时候调用这个函数 #### onRender 回调函数 :- | :- :- | :- `phase: "mount" \| "update"` | 判断是由 `props`/`state`/`hooks` 改变 或 “第一次装载” 引起的重渲染 `actualDuration: number` | 本次更新在渲染 Profiler 和它的子代上花费的时间 `baseDuration: number` | 在 Profiler 树中最近一次每一个组件 render 的持续时间 `startTime: number` | 本次更新中 React 开始渲染的时间戳 `commitTime: number` | 本次更新中 React commit 阶段结束的时间戳 `interactions: Set` | 当更新被制定时,“[interactions](https://fb.me/react-interaction-tracing)” 的集合会被追踪 默认值 --- ### Class 组件默认 props ```jsx class CustomButton extends React.Component { // ... } CustomButton.defaultProps = { color: 'blue' }; ``` #### 使用 ```jsx ; ``` 不传值 `props.color` 将自动设置为 `blue` ### Class 组件默认 state ```jsx class Hello extends Component { constructor (props) { super(props) this.state = { visible: true } } } ``` 在构造 `constructor()`中设置默认状态。 ```jsx class Hello extends Component { state = { visible: true } } ``` ### 函数组件默认 props ```jsx function CustomButton(props) { const { color = 'blue' } = props; return
    {color}
    } ``` ### 函数组件默认 state ```jsx function CustomButton() { const [color, setColor]=useState('blue') return
    {color}
    } ``` JSX --- ### 介绍 `JSX` 仅仅只是 `React.createElement(component, props, ...children)` 函数的语法糖 ```jsx 点击我 ``` 会编译为 ```js React.createElement( MyButton, {color: 'blue', shadowSize: 2}, '点击我' ); ``` 没有子节点 ```jsx
    ``` 会编译为 ```js React.createElement( 'div', {className: 'sidebar'} ) ``` ### JSX 点语法 ```jsx const Menu = ({ children }) => (
    {children}
    ); Menu.Item = ({ children }) => (
    {children}
    ); 菜单一 菜单二 ``` ### JSX Element ```jsx let element =

    Hello, world!

    ; let emptyHeading =

    ; const root = ReactDOM.createRoot( document.getElementById('root') ); const element =

    Hello, world

    ; root.render(element); ``` 参考:[渲染元素](https://reactjs.org/docs/rendering-elements.html) ### JSX 属性 ```jsx const avatarUrl = "img/picture.jpg" const element = ; const element = ( ); ``` 注意:类属性 `className` ### JSX 表达式 ```jsx let name = '张三'; let element =

    Hello, {name}

    ; function fullName(firstName, lastName) { return firstName + ' ' + lastName; } let element = (

    Hello, {fullName('三', '张')}

    ); ``` ### JSX style ```jsx const divStyle = { color: 'blue', backgroundImage: 'url(' + imgUrl + ')', }; function MyComponent() { return
    组件
    ; } ``` ### JSX dangerouslySetInnerHTML ```jsx const markup = {__html: '我 · 你' }; const MyComponent = () => (
    ); ``` `dangerouslySetInnerHTML` 是 React 为浏览器 DOM 提供 `innerHTML` 的替换方案。 ### JSX htmlFor ```jsx const MyComponent = () => (
    ); ``` `for` 在 `JS` 中是保留字,JSX 元素使用了 `htmlFor` 代替 ### JSX defaultValue 非受控组件的属性,设置组件第一次挂载时的 `value` ```jsx