专业编程基础技术教程

网站首页 > 基础教程 正文

React 最常用的函数(备忘查询)

ccvgpt 2024-11-24 12:29:52 基础教程 1 ℃

介绍

React 是一个用于构建用户界面的 JavaScript 库。

  • React 官方文档 (reactjs.org)
  • Styled Components 备忘清单 (jaywcjlove.github.io)
import {createRoot} from 'react-dom/client'
import App from './App'

const elm = document.getElementById('app')
const root = createRoot(elm);
root.render(<App />);

快速创建React项目 (CRA)

npx create-react-app my-app

导入多个导出

import React, {Component} from 'react'
import ReactDOM from 'react-dom'

export class Hello extends Component {
  ...
}
export default function World() {
  /* ... */
}

使用 export 导出 Hello,export default 导出 World 组件

React 最常用的函数(备忘查询)

import World, { Hello } from './hello.js';

使用 import 导入 Hello 组件,在示例中使用。

React 组件中的 CSS

import React from "react";
import "./Student.css";

export const Student = (
  <div className="Student"></div>
);

注意:类属性 className

const divStyle = {
  backgroundImage: 'url(' + imgUrl + ')',
};
export const Student = (
  <div style={divStyle}></div>
);

属性

<Student name="Julie" age={23}
  pro={true} />

函数组件 Student 中访问属性

function Student(props) {
  return <h1>Hello, {props.name}</h1>;
}

Class 组件 Student 中访问属性

class Student extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

class 组件使用 this.props 访问传递给组件的属性。

Children

function Example() {
  return (
    <AlertBox>
      <h1>您有待处理的通知</h1>
    </AlertBox>
  )
}

函数 AlertBox 组件

function AlertBox(props) {
  return (
    <div className="alert-box">
      {props.children}
    </div>
  );
}

{props.children}

Class AlertBox 组件,与函数组件 AlertBox 组件相同

class AlertBox extends React.Component {
  render () {
    return (
      <div className="alert-box">
        {this.props.children}
      </div>
    );
  }
}

{this.props.children}

children 作为子组件的的属性传递。

State

函数中的 State,Hook 是 React 16.8 的新增特性

import { useState } from 'react';

function Student() {
  const [count, setCount] = useState(0);
  const click = () => setCount(count + 1);
  return (
    <div>
      <p>您点击了 {count} 次</p>
      <button onClick={click}>
        点击我
      </button>
    </div>
  );
}

使用 setState 更新状态,下面是函数组件读取状态

<p>您点击了 {count} 次</p>

Class 中的 State

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 (
      <div>
        <button onClick={this.click}>
          点击我
        </button>
        <p>您点击了{this.state.count}次</p>
      </div>
    );
  }
}

使用 setState 更新状态,class 组件中不能使用 hooks。下面是 class 组件读取状态

<p>您点击了{this.state.count}次</p>

循环

const elm = ['one', 'two', 'three'];
function Student() {
  return (
    <ul>
      {elm.map((value, index) => (
        <li key={index}>{value}</li>
      ))}
    </ul>
  );
}

key 值在兄弟节点之间必须唯一

事件监听

export default function Hello() {
  function handleClick(event) {
    event.preventDefault();
    alert("Hello World");
  }

  return (
    <a href="/" onClick={handleClick}>
      Say Hi
    </a>
  );
}

函数注入

function addNumbers(x1, x2) {
  return x1 + x2;
}

const element = (
  <div>
    {addNumbers(2, 5)}
  </div>
);

嵌套

import { useState } from 'react'
import Avatar from './Avatar';
import Profile from './Profile';

function Student() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <Avatar src={count} />
      <Profile username={count} />
    </div>
  );
}

Portals

React 并_没有_创建一个新的 div。它只是把子元素渲染到 domNode 中。domNode 是一个可以在任何位置的有效 DOM 节点。

render() {
  return ReactDOM.createPortal(
    this.props.children,
    domNode
  );
}

提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案

Fragment

import { Fragment } from 'react'
import Avatar from './Avatar';
import Profile from './Profile';

const Student = () => (
  <Fragment>
    <Avatar src="./demo.jpg" />
    <Profile username="name" />
  </Fragment>
);

从 v16.2.0 开始 Fragment 可用于返回多个子节点,而无需向 DOM 添加额外的包装节点。或者使用 <></> 效果是一样的。

const Student = () => (
  <>
    <Avatar src="./demo.jpg" />
    <Profile username="name" />
  </>
);

查看: Fragments & strings

返回字符串

render() {
  return 'Look ma, no spans!';
}

您可以只返回一个字符串。查看: Fragments & strings

返回数组

const Student = () => [
  <li key="A">First item</li>,
  <li key="B">Second item</li>
];

不要忘记 key!查看: Fragments & strings

Refs 转发

const FancyButton = React.forwardRef(
  (props, ref) => (
    <button ref={ref} className="btn">
      {props.children}
    </button>
  )
);

使用

// 你可以直接获取 DOM button 的 ref:
const ref = React.createRef();

<FancyButton ref={ref}>
  点击我
</FancyButton>;

Class 组件内部使用 ref 属性

import {Component,createRef} from 'react'

class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.myRef = createRef();
  }

  render() {
    return <div ref={this.myRef} />;
  }
}

提示:Refs 适用于类组件,但不适用于函数组件(除非您使用 useRef hook,请参阅hooks)

函数组件内部使用 ref 属性

function CustomTextInput(props) {
  // 这里必须声明 $input,这样 ref 才可以引用它
  const $input = useRef(null);
  function handleClick() {
    $input.current.focus();
  }
  return (
    <div>
      <input type="text" ref={$input} />
      <input
        type="button" value="聚焦文本输入"
        onClick={handleClick}
      />
    </div>
  );
}

严格模式 StrictMode

<div>
  <Header />
  <React.StrictMode>
    <div>
      <ComponentOne />
      <ComponentTwo />
    </div>
  </React.StrictMode>
  <Footer />
</div>

  • 识别不安全的生命周期
  • 关于使用过时字符串 ref API 的警告
  • 关于使用废弃的 findDOMNode 方法的警告
  • 检测意外的副作用
  • 检测过时的 context API
  • 确保可复用的状态

突出显示应用程序中潜在问题的工具。请参阅:严格模式

Profiler

测量一个 React 应用多久渲染一次以及渲染一次的 代价

<Profiler id="Navigation" onRender={callback}>
  <Navigation {...props} />
</Profiler>

为了分析 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” 的集合会被追踪

默认值

Class 组件默认 props

class CustomButton extends React.Component {
  // ...
}
CustomButton.defaultProps = {
  color: 'blue'
};

使用

<CustomButton /> ;

不传值 props.color 将自动设置为 blue

Class 组件默认 state

class Hello extends Component {
  constructor (props) {
    super(props)
    this.state = { visible: true }
  }
}

在构造 constructor()中设置默认状态。

class Hello extends Component {
  state = { visible: true }
}

函数组件默认 props

function CustomButton(props) {
  const { color = 'blue' } = props;
  return <div>{color}</div>
}

函数组件默认 state

function CustomButton() {
  const [color, setColor]=useState('blue')
  return <div>{color}</div>
}

JSX

介绍

JSX 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖

<MyButton color="blue" shadowSize={2}>
  点击我
</MyButton>

会编译为

React.createElement(
  MyButton,
  {color: 'blue', shadowSize: 2},
  '点击我'
);

没有子节点

<div className="sidebar" />

会编译为

React.createElement(
  'div',
  {className: 'sidebar'}
)

JSX 点语法

const Menu = ({ children }) => (
  <div className="menu">{children}<div>
);

Menu.Item = ({ children }) => (
  <div>{children}<div>
);

<Menu>
  <Menu.Item>菜单一</Menu.Item>
  <Menu.Item>菜单二</Menu.Item>
<Menu>

JSX Element

let element = <h1>Hello, world!</h1>;
let emptyHeading = <h1 />;

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

const element = <h1>Hello, world</h1>;
root.render(element);

参考:渲染元素

JSX 属性

const avatarUrl = "img/picture.jpg"
const element = <img src={avatarUrl} />;

const element = (
  <button className="btn">
    点击我
  </button>
);

注意:类属性 className

JSX 表达式

let name = '张三';
let element = <h1>Hello, {name}</h1>;

function fullName(firstName, lastName) {
  return firstName + ' ' + lastName;
}
let element = (
  <h1>
    Hello, {fullName('三', '张')}
  </h1>
);

JSX style

const divStyle = {
  color: 'blue',
  backgroundImage: 'url(' + imgUrl + ')',
};
function MyComponent() {
  return <div style={divStyle}>组件</div>;
}

JSX dangerouslySetInnerHTML

const markup = {__html: '我 · 你' };

const MyComponent = () => (
  <div dangerouslySetInnerHTML={markup} />
);

dangerouslySetInnerHTML 是 React 为浏览器 DOM 提供 innerHTML 的替换方案。

JSX htmlFor

const MyComponent = () => (
  <div>
    <input type="radio" id="ab" name="v">
    <label for="ab">HTML</label>
  </div>
);

for 在 JS 中是保留字,JSX 元素使用了 htmlFor 代替

JSX defaultValue

非受控组件的属性,设置组件第一次挂载时的 value

<textarea defaultValue="Hello" />

<input>、<select> 和 <textarea> 支持 value 属性

JSX defaultChecked

非受控组件的属性,设置组件是否被选中

<input type="radio" defaultChecked />

类型为 checkbox 或 radio 时,组件支持 checked 属性

JSX className

属性用于指定 CSS 的 class

<div className="warp">...</div>

React 中使用 Web Components 使用 class 属性代替

JSX 条件渲染

import React from "react";

function formatName(user) {
  return user.firstName 
    + ' ' 
    + user.lastName;
}

export function Greeting(user) {
  if (user) {
    return (
      <h1>你好, {formatName(user)}!</h1>
    );
  }
  return (
    <h1>你好, 先生。</h1>
  );
}

注意:组件必须总是返回一些东西。

使用

<Greeting firstName="三" lastName="张" />

JSX 三目运算符 / 与运算符 &&

export default function Weather(props) {
  const isLoggedIn = props.isLoggedIn;
  return (
    <div>
      <b>{isLoggedIn ? '已' : '未'}</b>登录。
    </div>
  );
}

{isShow && <div>内容</div>}

JSX 组件

<Dropdown>
  下拉列表
  <Menu>
    <Menu.Item>菜单一</Menu.Item>
    <Menu.Item>菜单二</Menu.Item>
    <Menu.Item>菜单三</Menu.Item>
  </Menu>
</Dropdown>

组件名称以大驼峰式命名。

JSX 元素变量

function Greeting(props) {
  let button;
  if (props.isLoggedIn) {
    button = <UserGreeting />;
  } else {
    button = <GuestGreeting />;
  }
  return <div>{button}</div>;
}

JSX 注释

function Student() {
  const [count, setCount] = useState(0);
  return (
    <Fragment>
      {/* 这里写注释 */}
    </Fragment>
  );
}

组件

函数组件

import React from 'react';

const UserName = () => <h1>Kenny</h1>;

export default function UserProfile() {
  return (
    <div className="UserProfile">
      <div>Hello</div>  
      <UserName />
    </div>
  );
}

注意:每个组件都需要一个根元素,更多说明。

Class 组件

class Welcome extends React.Component {
  render() {
    return <h1>{this.props.name}</h1>;
  }
}

Class 组件 API

额外的 API

this.forceUpdate()

强制重新渲染

this.setState({ ... })

更新状态

this.setState(state =>{ ... })

更新状态

属性

defaultProps

默认 props

displayName

显示组件名称(用于调试)

实例属性

this.props

组件接受参数

this.state

组件内状态

Pure 组件

import React, {PureComponent} from 'react'

class MessageBox extends PureComponent {
  ···
}

高阶组件

import React, { Component } from 'react';
// 高阶组件 with
const with = data => WrappedComponent => {
  return class extends Component {
    constructor(props) {
      super(props);
    }
    render() {
      return (
        <WrappedComponent data={data} />
      )
    }
  }
}

使用高阶组件

const LowComponent = (props) => (
  <div>{props.data}</div>
);

const MyComp = with('Hello')(LowComponent)

包含关系

function FancyBorder(props) {
  return (
    <div className={'Fancy'+props.color}>
      {props.children}
    </div>
  );
}

组件可以通过 JSX 嵌套

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="title">欢迎</h1>
      <p className="message">
        感谢您访问我们的宇宙飞船
      </p>
    </FancyBorder>
  );
}

作为参数传递

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

function App() {
  return (
    <SplitPane
      left={<Contacts />}
      right={<Chat />}
    />
  );
}

给组件 SplitPane 传递 left 和 right 两个组件参数

嵌入内部组件

import React from 'react';
import UserAvatar from "./UserAvatar";

export default function UserProfile() {
  return (
    <div className="UserProfile">
      <UserAvatar />
      <UserAvatar />
    </div>
  );
}

注意:假设 UserAvatar 在 UserAvatar.js 中声明

嵌入外部组件

import React from 'react';
import {Button} from 'uiw';
export default function UserProfile() {
  return (
    <div className="UserProfile">
      <Button type="primary">
        主要按钮
      </Button>
    </div>
  );
}

注意:uiw 组件在 npmjs.com 上找到,需要先安装导入

点组件语法技巧

const Menu = ({ children }) => (
  <div className="menu">{children}<div>
);

Menu.Item = ({ children }) => (
  <div>{children}<div>
);

<Menu>
  <Menu.Item>菜单一</Menu.Item>
  <Menu.Item>菜单二</Menu.Item>
<Menu>

Hooks

Hooks API 参考

基础 Hook

useState

返回一个 state,更新 state 的函数 #

useEffect

可能有副作用代码的函数 #

useContext

接收并返回该 context 的当前值 #

额外的 Hook

useReducer

useState 的替代方案 #

useCallback

返回一个回调函数 #

useMemo

返回一个 memoized 值#

useRef

返回一个可变的 ref 对象 #

useImperativeHandle

暴露给父组件的实例值 #

useLayoutEffect

DOM 变更后同步调用函数 #

useDebugValue

开发者工具中显示标签 #

useDeferredValue

接受并返回该值的新副本 #

useTransition

过渡任务的等待状态 #

useId

用于生成唯一 ID #

Library Hooks

useSyncExternalStore

读取和订阅外部数据源 #

useInsertionEffect

DOM 突变之前 同步触发 #

函数式更新

function Counter({ initialCount }) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count} <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}

useRef

function TextInputWithFocusButton() {
  const $input = useRef(null);
  const onButtonClick = () => {
    $input.current.focus();
  };
  return (
    <>
      <input ref={$input} type="text" />
      <button onClick={onButtonClick}>
        聚焦输入
      </button>
    </>
  );
}

current 指向已挂载到 DOM 上的文本输入元素

useImperativeHandle

function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} />;
}
FancyInput = forwardRef(FancyInput);

父组件使用

<FancyInput ref={inputRef} />
inputRef.current.focus()

useEffect

useEffect(() => {
  const subs = props.source.subscribe();
  return () => {
    subs.unsubscribe();
  };
}, [props.source]);

useCallback

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

useMemo

const memoizedValue = useMemo(
  () => {
    return computeExpensiveValue(a, b)
  },
  [a, b]
);

useId

function Checkbox() {
  const id = useId();
  return (
    <>
      <label htmlFor={id}>
        你喜欢React吗?
      </label>
      <input id={id} type="checkbox" />
    </>
  );
};

用于生成跨服务端和客户端稳定的唯一 ID 的同时避免 hydration 不匹配

useDebugValue

function useFriendStatus(friendID) {
  const [
    isOnline, setIsOnline
  ] = useState(null);
  // ...
  // 在开发者工具中的这个 Hook 旁边显示标签
  // e.g. "FriendStatus: Online"
  useDebugValue(
    isOnline ? 'Online' : 'Offline'
  );
  return isOnline;
}

不推荐你向每个自定义 Hook 添加 debug 值

componentDidMount & componentWillUnmount

useEffect(
  () => {
    // componentDidMount
    // 组件挂载时,可以在这里完成你的任务
    return () => {
      // componentWillUnmount
      // 卸载时执行,清除 effect
    };
  },
  [ ]
);

这是一个类似 class 组件中 componentDidMount & componentWillUnmount 两个生命周期函数的写法。

生命周期

挂载

constructor (props)

渲染前 #

static getDerivedStateFromProps()

调用 render 方法之前调用 #

render()

class 组件中唯一必须实现的方法 #

componentDidMount()

在组件挂载后(插入 DOM 树中)立即调用 #

UNSAFE_componentWillMount()

在挂载之前被调用,建议使用 constructor() #

在 constructor() 上设置初始状态。在 componentDidMount() 上添加 DOM 事件处理程序、计时器(等),然后在 componentWillUnmount() 上删除它们。

卸载

componentWillUnmount()

在组件卸载及销毁之前直接调用 #

过时 API

componentWillMount()

UNSAFE_componentWillMount() #

componentWillReceiveProps()

UNSAFE_componentWillReceiveProps() #

componentWillUpdate()

UNSAFE_componentWillUpdate() #

17+ 之后不再支持,在 17 版本之后,只有新的 UNSAFE_ 生命周期名称可以使用。

更新

static getDerivedStateFromProps(props, state)

调用 render 之前调用,在初始挂载及后续更新时都会被调用 #

shouldComponentUpdate(nextProps, nextState)

如果返回 false,则跳过 render() #

render()

在不修改组件 state 的情况下,每次调用时都返回相同的结果 #

getSnapshotBeforeUpdate()

在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置) #

componentDidUpdate()

这里使用 setState(),但记得比较 props。首次渲染不会执行此方法 #

错误处理

static getDerivedStateFromError(error)

后代组件抛出错误后被调用,它将抛出的错误作为参数,并返回一个值以更新 state #

componentDidCatch(error, info)

在后代组件抛出错误后被调用,会在“提交”阶段被调用,因此允许执行副作用 #

render()

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

constructor()

constructor(props) {
  super(props);
  // 不要在这里调用 this.setState()
  this.state = { counter: 0 };
  this.handleClick = this.handleClick.bind(this);
}

static getDerivedStateFromError()

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染可以显降级 UI
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // 你可以渲染任何自定义的降级  UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

componentDidUpdate()

componentDidUpdate(prevProps) {
  // 典型用法(不要忘记比较 props):
  if (this.props.uid !== prevProps.uid) {
    this.fetchData(this.props.uid);
  }
}

getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate(prevProps, prevState) {
  // 我们是否在 list 中添加新的 items ?
  // 捕获滚动位置以便我们稍后调整滚动位置。
  if (prevProps.list.length < this.props.list.length) {
    const list = this.listRef.current;
    return list.scrollHeight - list.scrollTop;
  }
  return null;
}

PropTypes 属性类型检查

PropTypes

import PropTypes from 'prop-types'

any

任意类型

(props, propName, 组件名称)=>{}

自定义验证器

基础

string

字符串

number

数组

func

函数

bool

布尔值

symbol

-

枚举 Enum

oneOf(any)

枚举类型

oneOfType([type])

几种类型中的任意一个类型

数组 Array

array

数组

arrayOf

数组由某一类型的元素组成

对象 Object

object

对象

objectOf

对象由某一类型的值组成

instanceOf(...)

类的实例

shape

对象由特定的类型值组成

exact

有额外属性警告

元素 Elements

element

React 元素

elementType

React 元素类型(即 MyComponent)

node

DOM 节点

必需的

(···).isRequired

必需的

请参阅:使用 PropTypes 进行类型检查

基本类型

MyComponent.propTypes = {
  email:      PropTypes.string,
  seats:      PropTypes.number,
  callback:   PropTypes.func,
  isClosed:   PropTypes.bool,
  any:        PropTypes.any
  symbol:     PropTypes.symbol,
}

你可以将属性声明为 JS 原生类型,默认都是可选的。

必需的

MyComponent.propTypes = {
  // 确保这个 prop 没有被提供时,会打印警告信息
  requiredFunc: PropTypes.func.isRequired,

  // 任意类型的必需数据
  requiredAny: PropTypes.any.isRequired,
}

你可以在任何 PropTypes 属性后面加上 isRequired。

枚举

MyComponent.propTypes = {
  // 只能是特定的值,枚举类型。
  optionalEnum: PropTypes.oneOf([
    'News', 'Photos'
  ]),
  // 一个对象可以是几种类型中的任意一个类型
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),
}

元素 Elements

MyComponent.propTypes = {
  // 任何可被渲染的元素
  // (包括数字、字符串、元素或数组)
  // (或 Fragment) 也包含这些类型。
  node: PropTypes.node,

  // 一个 React 元素。
  element: PropTypes.element,

  // 一个 React 元素类型(即,MyComponent)
  elementType: PropTypes.elementType,
}

对象 Object

MyComponent.propTypes = {
  // 可以指定一个对象由某一类型的值组成
  objectOf: PropTypes.objectOf(
    PropTypes.number
  ),
  // 可以指定一个对象由特定的类型值组成
  objectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),
  // 带有额外属性警告的对象
  objectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number
  }),
}

自定义验证器

MyComponent.propTypes = {
  custom: (props, propName, compName) => {
    if (!/matchm/.test(props[propName])) {
      // 它在验证失败时应返回一个 Error 对象
      return new Error(
        '无效的prop `'
        ` \`${propName}\` 提供给` + 
        ` \`${compName}\`。验证失败。`
      );

    }
  },
}

请不要使用 console.warn 或抛出异常,因为这在 oneOfType 中不会起作用。

自定义的arrayOf或objectOf验证器

MyComponent.propTypes = {
  arrayProp: PropTypes.arrayOf((propValue, key, componentName, location, propFullName) => {
    if (!/matchme/.test(propValue[key])) {
      // 它应该在验证失败时返回一个 Error 对象。
      return new Error(
        'Invalid prop `' + propFullName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  })
}

propValue 是数组或对象本身,key 是他们当前的键。

数组

MyComponent.propTypes = {
  arr: PropTypes.arrayOf(PropTypes.number),
};

可以指定一个数组由某一类型的元素组成

验证类的实例

MyComponent.propTypes = {
  message: PropTypes.instanceOf(Message),
};

声明 message 为类的实例

React 官方中文文档 (zh-hans.reactjs.org)

Tags:

最近发表
标签列表