适合初学者的综合 React 备忘清单
入门
介绍
React 是一个用于构建用户界面的 JavaScript 库
1 2
| import {createRoot} from 'react-dom/client' import App from './App'
|
1 2 3
| const elm = document.getElementById('app') const root = createRoot(elm); root.render(<App />);
|
快速创建 React 项目 (CRA)
1
| npx create-react-app my-app
|
导入多个导出
1 2
| import React, {Component} from 'react' import ReactDOM from 'react-dom'
|
1 2 3 4 5 6
| export class Hello extends Component { ... } export default function World() { }
|
使用 export
导出 **Hello
**,export default
导出 World
组件
1
| import World, { Hello } from './hello.js';
|
使用 import
导入 Hello
组件,在示例中使用。
React 组件中的 CSS
{2,5}1 2 3 4 5 6
| import React from "react"; import "./Student.css";
export const Student = ( <div className="Student"></div> );
|
注意:类属性 className
1 2 3 4 5 6
| const divStyle = { backgroundImage: 'url(' + imgUrl + ')', }; export const Student = ( <div style={divStyle}></div> );
|
属性
1 2
| <Student name="Julie" age={23} pro={true} />
|
函数组件 Student
中访问属性
1 2 3
| function Student(props) { return <h1>Hello, {props.name}</h1>; }
|
Class 组件 Student
中访问属性
1 2 3 4 5 6 7
| class Student extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } }
|
class
组件使用 this.props
访问传递给组件的属性。
Children
1 2 3 4 5 6 7
| function Example() { return ( <AlertBox> <h1>您有待处理的通知</h1> </AlertBox> ) }
|
函数 AlertBox
组件
{4}1 2 3 4 5 6 7
| function AlertBox(props) { return ( <div className="alert-box"> {props.children} </div> ); }
|
Class AlertBox
组件,与函数组件 AlertBox
组件相同
{5}1 2 3 4 5 6 7 8 9
| class AlertBox extends React.Component { render () { return ( <div className="alert-box"> {this.props.children} </div> ); } }
|
children
作为子组件的的属性传递。
State
函数中的 State,Hook 是 React 16.8 的新增特性
{4,8}1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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
更新状态,下面是函数组件读取状态
Class 中的 State
{6,12,20}1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import React from 'react';
class Student extends React.Component { constructor(props) { super(props); this.state = {count: 1}; 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
组件读取状态
1
| <p>您点击了{this.state.count}次</p>
|
循环
1 2 3 4 5 6 7 8 9 10
| const elm = ['one', 'two', 'three']; function Student() { return ( <ul> {elm.map((value, index) => ( <li key={index}>{value}</li> ))} </ul> ); }
|
key
值在兄弟节点之间必须唯一
事件监听
1 2 3 4 5 6 7 8 9 10 11 12
| export default function Hello() { function handleClick(event) { event.preventDefault(); alert("Hello World"); }
return ( <a href="/" onClick={handleClick}> Say Hi </a> ); }
|
函数注入
1 2 3 4 5 6 7 8 9
| function addNumbers(x1, x2) { return x1 + x2; }
const element = ( <div> {addNumbers(2, 5)} </div> );
|
嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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 节点。
1 2 3 4 5 6
| render() { return ReactDOM.createPortal( this.props.children, domNode ); }
|
提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案
Fragment
{1,6,9}1 2 3 4 5 6 7 8 9 10
| 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 添加额外的包装节点。或者使用 <></>
效果是一样的。
{2,5}1 2 3 4 5 6
| const Student = () => ( <> <Avatar src="./demo.jpg" /> <Profile username="name" /> </> );
|
查看: Fragments & strings
返回字符串
{2}1 2 3
| render() { return 'Look ma, no spans!'; }
|
您可以只返回一个字符串。查看: Fragments & strings
返回数组
1 2 3 4
| const Student = () => [ <li key="A">First item</li>, <li key="B">Second item</li> ];
|
不要忘记 key
!查看: Fragments & strings
Refs 转发
1 2 3 4 5 6 7
| const FancyButton = React.forwardRef( (props, ref) => ( <button ref={ref} className="btn"> {props.children} </button> ) );
|
使用
1 2 3 4 5 6
| const ref = React.createRef();
<FancyButton ref={ref}> 点击我 </FancyButton>;
|
Class 组件内部使用 ref 属性
{6,10}1 2 3 4 5 6 7 8 9 10 11 12
| 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 属性
{3,9}1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function CustomTextInput(props) { const $input = useRef(null); function handleClick() { $input.current.focus(); } return ( <div> <input type="text" ref={$input} /> <input type="button" value="聚焦文本输入" onClick={handleClick} /> </div> ); }
|
严格模式 StrictMode
{3,8}1 2 3 4 5 6 7 8 9 10
| <div> <Header /> <React.StrictMode> <div> <ComponentOne /> <ComponentTwo /> </div> </React.StrictMode> <Footer /> </div>
|
突出显示应用程序中潜在问题的工具。请参阅:严格模式
Profiler
测量一个 React 应用多久渲染一次以及渲染一次的 代价
1 2 3
| <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
1 2 3 4 5 6
| class CustomButton extends React.Component { } CustomButton.defaultProps = { color: 'blue' };
|
使用
不传值 props.color
将自动设置为 blue
Class 组件默认 state
1 2 3 4 5 6
| class Hello extends Component { constructor (props) { super(props) this.state = { visible: true } } }
|
在构造 constructor()
中设置默认状态。
1 2 3
| class Hello extends Component { state = { visible: true } }
|
函数组件默认 props
1 2 3 4
| function CustomButton(props) { const { color = 'blue' } = props; return <div>{color}</div> }
|
函数组件默认 state
1 2 3 4
| function CustomButton() { const [color, setColor]=useState('blue') return <div>{color}</div> }
|
JSX
介绍
JSX
仅仅只是 React.createElement(component, props, ...children)
函数的语法糖
1 2 3
| <MyButton color="blue" shadowSize={2}> 点击我 </MyButton>
|
会编译为
1 2 3 4 5
| React.createElement( MyButton, {color: 'blue', shadowSize: 2}, '点击我' );
|
没有子节点
1
| <div className="sidebar" />
|
会编译为
1 2 3 4
| React.createElement( 'div', {className: 'sidebar'} )
|
JSX 点语法
1 2 3 4 5 6 7 8 9 10 11 12
| 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
1 2 3 4 5 6 7 8 9
| 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 属性
1 2 3 4 5 6 7 8
| const avatarUrl = "img/picture.jpg" const element = <img src={avatarUrl} />;
const element = ( <button className="btn"> 点击我 </button> );
|
注意:类属性 className
JSX 表达式
1 2 3 4 5 6 7 8 9 10 11
| let name = '张三'; let element = <h1>Hello, {name}</h1>;
function fullName(firstName, lastName) { return firstName + ' ' + lastName; } let element = ( <h1> Hello, {fullName('三', '张')} </h1> );
|
JSX style
1 2 3 4 5 6 7
| const divStyle = { color: 'blue', backgroundImage: 'url(' + imgUrl + ')', }; function MyComponent() { return <div style={divStyle}>组件</div>; }
|
JSX dangerouslySetInnerHTML
1 2 3 4 5
| const markup = {__html: '我 · 你' };
const MyComponent = () => ( <div dangerouslySetInnerHTML={markup} /> );
|
dangerouslySetInnerHTML
是 React 为浏览器 DOM 提供 innerHTML
的替换方案。
JSX htmlFor
1 2 3 4 5 6
| const MyComponent = () => ( <div> <input type="radio" id="ab" name="v"> <label for="ab">HTML</label> </div> );
|
for
在 JS
中是保留字,JSX 元素使用了 htmlFor
代替
JSX defaultValue
非受控组件的属性,设置组件第一次挂载时的 value
1
| <textarea defaultValue="Hello" />
|
<input>
、<select>
和 <textarea>
支持 value 属性
JSX defaultChecked
非受控组件的属性,设置组件是否被选中
1
| <input type="radio" defaultChecked />
|
类型为 checkbox
或 radio
时,组件支持 checked 属性
JSX className
属性用于指定 CSS
的 class
1
| <div className="warp">...</div>
|
React 中使用 Web Components 使用 class
属性代替
JSX 条件渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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> ); }
|
注意:组件必须总是返回一些东西。
使用
1
| <Greeting firstName="三" lastName="张" />
|
JSX 三目运算符 / 与运算符 &&
1 2 3 4 5 6 7 8
| export default function Weather(props) { const isLoggedIn = props.isLoggedIn; return ( <div> <b>{isLoggedIn ? '已' : '未'}</b>登录。 </div> ); }
|
1
| {isShow && <div>内容</div>}
|
JSX 组件
1 2 3 4 5 6 7 8
| <Dropdown> 下拉列表 <Menu> <Menu.Item>菜单一</Menu.Item> <Menu.Item>菜单二</Menu.Item> <Menu.Item>菜单三</Menu.Item> </Menu> </Dropdown>
|
组件名称以大驼峰式命名。
JSX 元素变量
1 2 3 4 5 6 7 8 9
| function Greeting(props) { let button; if (props.isLoggedIn) { button = <UserGreeting />; } else { button = <GuestGreeting />; } return <div>{button}</div>; }
|
JSX 注释
1 2 3 4 5 6 7 8
| function Student() { const [count, setCount] = useState(0); return ( <Fragment> {/* 这里写注释 */} </Fragment> ); }
|
组件
函数组件
1 2 3 4 5 6 7 8 9 10 11 12
| import React from 'react';
const UserName = () => <h1>Kenny</h1>;
export default function UserProfile() { return ( <div className="UserProfile"> <div>Hello</div> <UserName /> </div> ); }
|
注意:每个组件都需要一个根元素,更多说明。
Class 组件
1 2 3 4 5
| 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 组件
1 2 3 4 5
| import React, {PureComponent} from 'react'
class MessageBox extends PureComponent { ··· }
|
高阶组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React, { Component } from 'react';
const with = data => WrappedComponent => { return class extends Component { constructor(props) { super(props); } render() { return ( <WrappedComponent data={data} /> ) } } }
|
使用高阶组件
1 2 3 4 5
| const LowComponent = (props) => ( <div>{props.data}</div> );
const MyComp = with('Hello')(LowComponent)
|
包含关系
1 2 3 4 5 6 7
| function FancyBorder(props) { return ( <div className={'Fancy'+props.color}> {props.children} </div> ); }
|
组件可以通过 JSX 嵌套
1 2 3 4 5 6 7 8 9 10
| function WelcomeDialog() { return ( <FancyBorder color="blue"> <h1 className="title">欢迎</h1> <p className="message"> 感谢您访问我们的宇宙飞船 </p> </FancyBorder> ); }
|
作为参数传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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
两个组件参数
嵌入内部组件
{2}1 2 3 4 5 6 7 8 9 10 11
| import React from 'react'; import UserAvatar from "./UserAvatar";
export default function UserProfile() { return ( <div className="UserProfile"> <UserAvatar /> <UserAvatar /> </div> ); }
|
注意:假设 UserAvatar
在 UserAvatar.js
中声明
嵌入外部组件
{2}1 2 3 4 5 6 7 8 9 10 11
| import React from 'react'; import {Button} from 'uiw'; export default function UserProfile() { return ( <div className="UserProfile"> <Button type="primary"> 主要按钮 </Button> </div> ); }
|
注意:uiw 组件在 npmjs.com 上找到,需要先安装导入
点组件语法技巧
1 2 3 4 5 6 7
| const Menu = ({ children }) => ( <div className="menu">{children}<div> );
Menu.Item = ({ children }) => ( <div>{children}<div> );
|
1 2 3 4
| <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 突变之前 同步触发 # |
函数式更新
1 2 3 4 5 6 7 8 9 10
| 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function TextInputWithFocusButton() { const $input = useRef(null); const onButtonClick = () => { $input.current.focus(); }; return ( <> <input ref={$input} type="text" /> <button onClick={onButtonClick}> 聚焦输入 </button> </> ); }
|
current
指向已挂载到 DOM 上的文本输入元素
useImperativeHandle
1 2 3 4 5 6 7 8 9 10
| function FancyInput(props, ref) { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); } })); return <input ref={inputRef} />; } FancyInput = forwardRef(FancyInput);
|
父组件使用
1 2
| <FancyInput ref={inputRef} /> inputRef.current.focus()
|
useEffect
1 2 3 4 5 6
| useEffect(() => { const subs = props.source.subscribe(); return () => { subs.unsubscribe(); }; }, [props.source]);
|
useCallback
1 2 3 4 5 6
| const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], );
|
useMemo
1 2 3 4 5 6
| const memoizedValue = useMemo( () => { return computeExpensiveValue(a, b) }, [a, b] );
|
useId
1 2 3 4 5 6 7 8 9 10 11
| function Checkbox() { const id = useId(); return ( <> <label htmlFor={id}> 你喜欢React吗? </label> <input id={id} type="checkbox" /> </> ); };
|
用于生成跨服务端和客户端稳定的唯一 ID
的同时避免 hydration
不匹配
useDebugValue
1 2 3 4 5 6 7 8 9 10 11 12
| function useFriendStatus(friendID) { const [ isOnline, setIsOnline ] = useState(null); useDebugValue( isOnline ? 'Online' : 'Offline' ); return isOnline; }
|
不推荐你向每个自定义 Hook
添加 debug
值
componentDidMount & componentWillUnmount
1 2 3 4 5 6 7 8 9 10 11
| useEffect( () => { return () => { }; }, [ ] );
|
这是一个类似 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()
{2}1 2 3 4 5
| class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
|
constructor()
{1}1 2 3 4 5 6
| constructor(props) { super(props); this.state = { counter: 0 }; this.handleClick = this.handleClick.bind(this); }
|
static getDerivedStateFromError()
{7,13}1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; }
static getDerivedStateFromError(error) { return { hasError: true }; }
render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; }
return this.props.children; } }
|
componentDidUpdate()
{1}1 2 3 4 5 6
| componentDidUpdate(prevProps) { if (this.props.uid !== prevProps.uid) { this.fetchData(this.props.uid); } }
|
getSnapshotBeforeUpdate()
1 2 3 4 5 6 7 8 9
| getSnapshotBeforeUpdate(prevProps, prevState) { if (prevProps.list.length < this.props.list.length) { const list = this.listRef.current; return list.scrollHeight - list.scrollTop; } return null; }
|
PropTypes 属性类型检查
PropTypes
1
| 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 进行类型检查
基本类型
1 2 3 4 5 6 7 8
| MyComponent.propTypes = { email: PropTypes.string, seats: PropTypes.number, callback: PropTypes.func, isClosed: PropTypes.bool, any: PropTypes.any symbol: PropTypes.symbol, }
|
你可以将属性声明为 JS 原生类型,默认都是可选的。
必需的
1 2 3 4 5 6 7
| MyComponent.propTypes = { requiredFunc: PropTypes.func.isRequired,
requiredAny: PropTypes.any.isRequired, }
|
你可以在任何 PropTypes
属性后面加上 isRequired
。
枚举
1 2 3 4 5 6 7 8 9 10 11 12
| MyComponent.propTypes = { optionalEnum: PropTypes.oneOf([ 'News', 'Photos' ]), optionalUnion: PropTypes.oneOfType([ PropTypes.string, PropTypes.number, PropTypes.instanceOf(Message) ]), }
|
元素 Elements
1 2 3 4 5 6 7 8 9 10 11 12
| MyComponent.propTypes = { node: PropTypes.node,
element: PropTypes.element,
elementType: PropTypes.elementType, }
|
对象 Object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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 }), }
|
自定义验证器
1 2 3 4 5 6 7 8 9 10 11 12 13
| MyComponent.propTypes = { custom: (props, propName, compName) => { if (!/matchm/.test(props[propName])) { return new Error( '无效的prop `' ` \`${propName}\` 提供给` + ` \`${compName}\`。验证失败。` );
} }, }
|
请不要使用 console.warn
或抛出异常,因为这在 oneOfType
中不会起作用。
自定义的 arrayOf
或 objectOf
验证器
1 2 3 4 5 6 7 8 9 10 11
| MyComponent.propTypes = { arrayProp: PropTypes.arrayOf((propValue, key, componentName, location, propFullName) => { if (!/matchme/.test(propValue[key])) { return new Error( 'Invalid prop `' + propFullName + '` supplied to' + ' `' + componentName + '`. Validation failed.' ); } }) }
|
propValue
是数组或对象本身,key
是他们当前的键。
数组
1 2 3
| MyComponent.propTypes = { arr: PropTypes.arrayOf(PropTypes.number), };
|
可以指定一个数组由某一类型的元素组成
验证类的实例
1 2 3
| MyComponent.propTypes = { message: PropTypes.instanceOf(Message), };
|
声明 message
为类的实例
另见