引入React
import * as React from 'react'
import * as ReactDom from 'react-dom'
复制代码
这种引入方式被认为是最可靠的一种方式,推荐使用
另一种引入方式:
import React from 'react'
import ReactDom from 'react-dom'
复制代码
需要添加额外的配置:"allowSyntheticDefaultImports": true,
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
复制代码
函数式组件声明方式
第一种:React.FunctionComponent
比较推荐的一种,简写形式React.FC
type AppProps = {
message: string
}
const App: React.FC<AppProps> = ({ message, children }) => (
<div>
{message}
{children}
</div>
)
复制代码
使用React.FC
声明函数组件和普通声明以及PropsWithChildren的区别:
- React.FC显式的定义了返回类型,其他方式是隐式推导
- React.FC对静态属性:displayName,propTypes,defaultProps提供了类型检查和自动补全
- React.FC为children提供了隐式类型(ReactElement|null),但是目前提供的类型存在一些问题
比如以下用法React.FC会报类型错误:
const App: React.FC = props => props.children
const App: React.FC = () => [1, 2, 3]
const App: React.FC = () => 'hello'
复制代码
解决办法:
const App: React.FC<{}> = props => props.children as any
const App: React.FC<{}> = () => [1, 2, 3] as any
const App: React.FC<{}> = () => 'hello' as any
// 或者
const App: React.FC<{}> = props => (props.children as unknown) as JSX.Element
const App: React.FC<{}> = () => ([1, 2, 3] as unknown) as JSX.Element
const App: React.FC<{}> = () => ('hello' as unknown) as JSX.Element
复制代码
在通常情况下,使用React.FC
的方式声明最简单有效,推荐使用;如果出现类型不兼容问题,建议以下两种方式
第二种:PropsWithChildren
这种方式可以省去频繁定义children的类型,自动设置children类型为ReactNode:
type AppProps = React.PropsWithChildren<{ message: string }>
const App = ({ message, children }: AppProps) => (
<div>
{message}
{children}
</div>
)
复制代码
第三种:直接声明
type AppProps = {
message: string
children?: React.ReactNode
}
const App = ({ message, children }: AppProps) => (
<div>
{message}
{children}
</div>
)
复制代码
Hooks
use State<T>
返回一个 state,以及更新 state 的函数
大部分情况下ts会自动推导state的类型:
// `val`会推导为boolean类型, toggle接收boolean类型参数
const [val, toggle] = React.useState(false)
// obj会自动推导为类型: {name: string}
const [obj] = React.useState({ name: 'sj' })
// arr会自动推导为类型: string[]
const [arr] = React.useState(['One', 'Two'])
复制代码
使用推导类型作为接口/类型:
export default function App() {
// user会自动推导为类型: {name: string}
const [user] = React.useState({ name: 'sj', age: 32 })
const showUser = React.useCallback((obj: typeof user) => {
return `My name is ${obj.name}, My age is ${obj.age}`
}, [])
return <div className="App">用户: {showUser(user)}</div>
}
复制代码
但是,一些状态初始值为空(null
)时,需要显式的声明类型:
type User = {
name: string
age: number
}
const [user, setUser] = React.useState<User | null>(null)
复制代码
useRef<T>
useRef
返回一个可变的ref对象,其.current
属性被初始化为传入的参数。返回的ref对象在组件的整个生命周期内保持不变
当初始值为null
时,有两种创建方式
const ref1 = React.useRef<HTMLInputElement>(null)
const ref2 = React.useRef<HTMLInputElement | null>(null)
复制代码
这两种的区别在于:
- 第一种方式的ref1.current是只读的,并且可以传递给内置的ref属性,绑定DOM元素
- 第二种方式的ref2.current是可变的(类似于声明类的成员变量)
const ref = React.useRef(0)
React.useEffect(() => {
ref.current += 1
}, [])
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END