TypeScript && React
2019-09-15 17:51
2036 查看
环境搭建
我们当然可以先用脚手架搭建React项目,然后手动配置成支持TypeScript的环境,虽然比较麻烦,但可以让你更清楚整个过程。这里比较麻烦,就不演示了,直接用命令配置好。
npx create-react-app appname --typescript
可以安装一些自己需要的库及其声明文件,例如react-router-dom、axios、ant Design等。如果要安装ant design,还需要在开发环境库中安装一些依赖库,以帮助实现按需加载。
使用
有类型约束的函数组件
import React from "react"; import { Button } from "antd"; interface Greeting { name: string; firstName?: string; lastName?: string; } // 没有使用React.FC const HelloOld = (props: Greeting) => <Button>你好{props.name}</Button>; // 使用React.FC泛型类型 const Hello: React.FC<Greeting> = (props) => { return ( <Button>Hello {props.name}</Button> ) }; export { Hello, HelloOld };
定义函数组件时,使用React.FC与不使用没有太多区别,没有为我们带来明显的好处,建议使用常规定义方式。
有类型约束的类组件
import React,{Fragment} from "react"; import { Button } from "antd"; interface Greeting { name: string; firstName?: string; lastName?: string; } interface State { count: number } // 泛型类型,第一个传入参数约束属性props,第二个约束状态state(内部数据) class HelloClass extends React.Component<Greeting, State> { state: State = { count: 0 }; static defaultProps = { // 属性默认值 firstName: "", lastName: "", }; render() { return ( <Fragment> <p>点击了{this.state.count}次</p> <Button onClick={()=>{this.setState({count: this.state.count+1})}}>Hello{this.props.name}Class</Button> </Fragment> ); } } export default HelloClass;
有类型约束的高阶组件
import React from "react"; import HelloClass from "./HelloClass"; interface Loading { loading: boolean; } function HelloHoc<P>(params?: any) { return function<P>(WrappedComponent: React.ComponentType<P>) { // P表示被包装组件的属性的类型 return class NewComponent extends React.Component<P & Loading>{ // 这里使用交叉类型,为新组件增加一些属性,接口Loading定义了新增的属性声明 render(){ return this.props.loading ? <div>Loading</div> : <WrappedComponent {...this.props as P}/> } } } } export default HelloHoc()(HelloClass);
高阶组件在ts中使用会有比较多的类型问题,解决这些问题通常不会很顺利,而且会存在一些已知的bug,这不是高阶组件本身的问题,而是React声明文件还没有很好地兼容高阶组件的类型检查,更好的方式是使用Hooks
有类型约束的Hooks
import React, { useState, useEffect } from "react"; import { Button } from "antd"; interface Greeting { name: string; firstName?: string; lastName?: string; } const HelloHooks = (props: Greeting) => { const [ count, setCount ] = useState(0); // 设了初值,所以不用定义类型 const [ text, setText ] = useState<string | null>(null); useEffect(()=>{ count > 5 && setText("休息一下"); },[count]); // 第二个参数的作用是,只有当count改变的时候,函数内的逻辑才会执行。 return ( <> <p>你点击了Hooks {count} 次 {text}</p> <Button onClick={()=>{setCount(count+1)}}>{props.name}</Button> </> ); }; export default HelloHooks;
事件绑定
class HelloClass extends React.Component<Greeting, State> { state: State = { count: 0 }; clickHandle = (e: React.MouseEvent) => { // 事件对象e的类型使用内置的合成事件。在回调函数中,e的属性都会无效 e.persist(); // 将该事件从池中删除合成事件,可以正常使用 console.log(e); // this.setState({count: this.state.count+1}) }; inputHandle = (e: React.FormEvent<HTMLInputElement>) => { // e.persist(); console.log(e.currentTarget.value); // 此时编译器报错,认为没有value属性,需要指定<HTMLInputElement>泛型类型 // console.log(e.target.value); // 仍然不行 }; render() { return ( <Fragment> <p>点击了{this.state.count}次</p> <Button onClick={this.clickHandle}>Hello{this.props.name}Class</Button> <input onChange={this.inputHandle}/> </Fragment> ); } }
相关文章推荐
- typeScript.webpack&react的正确版quickStart
- React-native学习笔记之<BackAndroid>
- TypeScript & JavaScript
- 使用react-native-pull实现跨平台Android&IOS下拉刷新滑动回弹效果
- React-小白笔记之受限组件 & 小坑
- TypeScript+React+Redux 简单天气预报系统
- 从零开始的Android新项目10 - React Native & Redux
- webpack 3 & React 的配置 。
- 为什么作为Android开发想学学React&&React Native?
- react & Vue.js
- React-Native学习笔记1—环境搭建[Linux & Windows]
- React官方文档—9.列表 & Keys
- React_Native 再学习5--TypeScript学习1_基础语法
- react的应用之道——实践&&领悟
- React 脚手架 && 相关demo
- ReactJS & antd 环境中项目运行时错误总结
- [React Native + Firebase] React Native: Real time database with Firebase -- setup & CRUD
- [ReactNative] 02--style & width/height & FlexBox
- react-native-easy-toast, 一款简单易用的 Toast 组件,支持 Android&iOS.
- React环境搭建之二:node.js & npm安装