无需TypeScript,如何为React Hooks及类组件的State做类型检查?
React无TypeScript下的State类型检查方案
因为prop-types仅针对组件Props提供校验,默认不支持State的类型检查,以下是两种轻量方案,适配函数组件和类组件,且仅在开发环境生效:
一、函数组件:封装带类型校验的useState Hook
基于原生useState封装自定义Hook,利用prop-types的校验能力,在设置State时做类型检查:
import { useState } from 'react'; import PropTypes from 'prop-types'; // 封装带类型检查的useState function useTypedState(initialValue, propType) { // 仅在开发环境执行校验 if (process.env.NODE_ENV === 'development') { PropTypes.checkPropTypes({ value: propType }, { value: initialValue }, 'state', 'useTypedState'); } const [state, setState] = useState(initialValue); const typedSetState = (newValue) => { if (process.env.NODE_ENV === 'development') { PropTypes.checkPropTypes({ value: propType }, { value: newValue }, 'state', 'useTypedState'); } setState(newValue); }; return [state, typedSetState]; } // 使用示例 export function GreetingHook(props) { // 指定name2必须是string类型,初始值10会在开发环境触发警告 const [name2, setName2] = useTypedState(10, PropTypes.string); return ( <h1>Hello, {props.name}</h1> ); } GreetingHook.propTypes = { name: PropTypes.string, };
二、类组件:重写setState方法加入校验
在类组件内部重写setState,在更新State前做类型校验:
import React from 'react'; import PropTypes from 'prop-types'; class GreetingClass extends React.Component { // 定义State的类型规则 static stateTypes = { name2: PropTypes.string, }; constructor(props) { super(props); this.state = { name2: 10, // 开发环境会触发校验警告 }; // 保存原生setState并绑定重写后的方法 this.originalSetState = this.setState; this.setState = this.typedSetState.bind(this); } typedSetState(newState, callback) { if (process.env.NODE_ENV === 'development') { // 处理函数式更新的情况,校验最终生成的state const targetState = typeof newState === 'function' ? newState(this.state) : newState; PropTypes.checkPropTypes( GreetingClass.stateTypes, targetState, 'state', GreetingClass.name ); } this.originalSetState(newState, callback); } render() { return <h1>Hello, {this.props.name}</h1>; } } GreetingClass.propTypes = { name: PropTypes.string, };
注意事项
- 校验逻辑仅在开发环境执行,生产环境会自动忽略(依赖项目构建时正确设置
process.env.NODE_ENV环境变量)。 - 复杂嵌套结构的State,可直接使用prop-types的嵌套校验规则(比如
PropTypes.shape)。
内容的提问来源于stack exchange,提问作者lingar
相关产品推荐
相关产品推荐

