React.FunctionComponent

React提供了一个组件类型React.FunctionComponent,可简写React.FC

  • 能够接管一个泛型p,默认是{}
  • children,返回一个React.ReactNode,这个children是任何component都领有的
  • 动态属性defaultProps,组件的默认属性,内部能够不传这个属性。
interface IHelloProps {  message?: string;}const Hello: React.FunctionComponent<IHelloProps> = (props) => {  return <h2>{props.message}</h2>;};Hello.defaultProps = {  message: "Hello  world",};

React Hook

  • 齐全可选
  • 百分百向后兼容
  • 没有打算从React移除class

Hook是一个非凡的函数,它能够让你勾入React个性,例如useState就容许在React函数组件增加state Hook

在编写函数组件时,意识到要向外面增加一些State时,以前的做法是必须转换成Class类型的组件,当初能够在现有的函数组件中应用Hook

useState

离开应用

import React, { useState } from "react";const LikeButton: React.FC = () => {  const [like, setLike] = useState(0);  const [on, setOn] = useState(true);  return (    <>      <button        onClick={() => {          setLike(like + 1);        }}      >        {like}????      </button>      <button        onClick={() => {          setOn(!on);        }}      >        {on ? "ON" : "OFF"}      </button>    </>  );};export default LikeButton;

合在一起应用

import React, { useState } from "react";const LikeButton: React.FC = () => {  const [obj, setObj] = useState({ like: 1, on: true });  return (    <>      <button        onClick={() => {          setObj({ like: obj.like + 1, on: obj.on });        }}      >        {obj.like}????      </button>      <button        onClick={() => {          setObj({ like: obj.like, on: !obj.on });        }}      >        {obj.on ? "ON" : "OFF"}      </button>    </>  );};export default LikeButton;

删除数据

react 中有一个概念 immutable ,意思是不容许 state 有任何的扭转。

一旦批改 state ,前面做 react 性能做优化的时候会有问题。

const { list } = [...this.state.list];list.splice(1, 1);this.setState({ list });// 不举荐this.state.list.splice(1, 1);this.setState({ list: this.state.list });

属性名

labelfor 属性,在 jsx 中会和 for 循环抵触, reacthtmlFor 来代替 label 标签的 for

<label htmlFor='insertArea'>姓名</label><input type='text' id='insertArea'/>

父组件和子组件通信

子组件操作父组件的数据:

  1. 父组件向子组件传递一个办法
  2. 子组件调用这个办法,间接的操作父组件的数据
class TodoList extends Component {  deleteItem = (number) => {    alert(number);  };  render() {    return <TodoItem deleteItem={this.deleteItem} />;  }}class TodoItem extends Component {  constructor(props) {    super(props);  }  render() {    return <div onClick={this.props.deleteItem(1)}>按钮</div>;  }}

setState 接管函数

onClick(e) {    const value = e.target.value    this.setState(() => ({        value    }))}onClick() {    // prevState 是批改前的数据状态    this.setState((prevState) => ({        list: [...prevState.list]    }))}

PropTypes

限度父组件向子组件传值的类型

import PropTypes from "prop-types";TodoItem.propTypes = {  test: PropTypes.string.isRequired,  content: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),  deleteItem: PropTypes.func,  index: PropTypes.number,};

defaultProps

属性默认值

TodoItem.defaultProps = {  test: "hello world",};

虚构 DOM

当父组件的 render 函数被运行时,它的子组件的 render 也会被从新执行

  1. state 数数据
  2. JSX 模版
  3. 数据 + 模版 生成虚构 DOM(虚构 DOM 就是一个 js 对象,用它来形容正式的 DOM),(损耗了性能)。

    ["div", { id: "name" }, ["span", {}, "hello world"]];
  4. 用虚构 DOM 的构造生成实在的 DOM,来显示

    <div id="abc"><span>abc</span></div>
  5. state 发生变化(setState 时,数据会发生变化)
  6. 数据 + 模版 生成新的虚构 DOM(极大晋升了性能),diff 算法,react 中的 diff 是同层比拟,如果第一层节点就产生了变动,上面就不在比拟了,间接全副替换

    ["div", { id: "name" }, ["span", {}, "bye bye"]];
  7. 比拟原始虚构 DOM 和新的虚构 DOM 的区别,找到区别的是 span 中的内容(极大晋升了性能)
  8. 间接操作 DOM,扭转 span 中的内容

Ref

react 倡议用数据驱动,尽量不要去操作 DOM

<input onChange={this.onChange} ref={(input) => (this.input = input)} />;onChange = (e) => {  const value = this.input.value;  // 等价于  const value = e.target.value;};

申明周期函数

  • componentWillMount:组件在行将被挂载到页面时执行(第一次挂载的时候被执行)
  • render
  • componentDidMount:组件在被挂载到页面后执行(第一次挂载的时候被执行),ajax 申请最好发在这里
  • shouldComponentUpdate:组件被更新之前执行(须要在函数外部返回 true,返回 false 不会执行)
  • componentWillUpdate:组件被更新之前执行,但在 shouldComponentUpdate 之后(shouldComponentUpdate 返回 true 才会被执行)
  • componentDidUpdate:组件更新完之后执行
  • componentWillReceiveProps:没有 props 参数,不会被执行

    1. 一个组件要从父组件接管参数
    2. 只有父组件的 render 函数被从新执行了,子组件的 componentWillReceiveProps 就会被执行(如果子组件第一次呈现在页面中,不会执行)
  • componentWillUnmount:组件被移除前执行

shouldComponentUpdate

/** * nextProps 一个组件更新时 props 会变动成什么样 * nextState 一个组件更新时 state 会变动成什么样 */shouldComponentUpdate(nextProps, nextState) {    if(nextProps.content !== this.props.content) {        return true    } else {        return false    }}

动画

装置 react-transition-group

import { CSSTransition } from "react-transtion-group";<CSSTransition  in={this.stata.show} // 通知 CSSTransition 组件什么时候有动画  timeout={1000} // 动画时长 1s  className="fade"  unmountOnExit // 元素隐没后会被移除  appear={true} // 页面一刷新,也会有动画成果>  <div>hello</div></CSSTransition>;
  • fade-enter(动画进入前一瞬间)
  • fade-enter-active(动画进入前第二霎时,始终到动画实现)
  • fade-enter-done(进入动画实现时)
  • fade-exit(动画隐没前一瞬间)
  • fade-exit-active(动画隐没前第二霎时,始终到动画隐没实现)
  • fade-exit-done(隐没动画实现时)
  • fade-appear(动画进入前一瞬间)
  • fade-appear-active(动画进入前第二霎时,始终到动画实现)