正文
ts 在中 在react 用处很是很广泛,本文是一篇关于在 react 中常用的类型总结,希望能带来一些思考和帮助。
一个函数组件import React from "react"; type Props = { } const Header: React.FC<Props> = (props) => { return (<> <div>header</div> {props.children} </>) }
我们注意在 Header 组件中有使用到 props.children 如果 Props 没有申明类型那么此时就会报这样的错误
此时我们需要加个类型就行,并且 children 是可选的
import React from "react"; interface Props { children?: React.ReactNode; }
除了 children ,有时我想给 Header 组件传入一个 className ,并且是可选的
import React from "react"; type Props = { children?: React.ReactNode; className?: string; } const Header: React.FC<Props> = (props) => { const { className } = props; return (<> <div className={`App-header ${className}`}>header</div> {props.children} </>) }
在 Props 我们似乎对每一个可选项都有做 ? 可选,有没有一劳永逸的办法
Partial<T> 所有属性都是可选
import React from "react"; type Props = { children: React.ReactNode; className: string; } const Header: React.FC<Partial<Props>> = (props) => { const { className = '' } = props; return (<> <div className={`App-header ${className}`}>header</div> {props.children} </>) }
在以上我们给 Props 申明了一个 children?: React.ReactNode ,如果你不想这么写, react 也提供了一个属性 PropsWithChildren
interface ChildProps {} export const SubHeader: React.FC = ( props: PropsWithChildren<{}> & Partial<ChildProps> ) => { return <div className={`sub-header`}>{props.children}</div>; };
在dom节点上的类型
import React, { PropsWithChildren, useRef } from "react"; const Input: React.FC = () => { const inputRef = useRef<HTMLInputElement>(null); const sureRef = useRef<HTMLDivElement>(null); return ( <> <input type="text" ref={inputRef} /> <div ref={sureRef}>确定</div> </> ); };
传入子组件的方法
我想传入一个方法到子组件里去
type InputProps = { onSure: () => void; }; const Input: React.FC<InputProps> = (props) => { const inputRef = useRef<HTMLInputElement>(null); const sureRef = useRef<HTMLDivElement>(null); return ( <> <input type="text" ref={inputRef} /> <div ref={sureRef} onClick={props?.onSure}> 确定 </div> </> ); }; const Index: React.FC<Partial<Props>> = (props) => { const { className } = props; const handleSure = () => {}; return ( <header className={`App-header ${className}`}> <Input onSure={handleSure} /> {props.children} </header> ); };
!非空断言,一定有该方法或者属性
const body = document!.getElementsByTagName("body")[0]; body.addEventListener("click", () => { console.log("body"); });
一个doms上的类型
在 sure 按钮上用ref绑定一个dom
const Input: React.FC<InputProps> = (props) => { const inputRef = useRef<HTMLInputElement>(null); const sureRef = useRef(null); const body = document!.getElementsByTagName("body")[0]; body.addEventListener("click", () => { console.log(sureRef.current?.style); console.log("body"); }); return ( <> <input type="text" ref={inputRef} /> <div ref={sureRef} onClick={props?.onSure}> 确定 </div> </> ); };
此时我们需要给 sureRef 申明类型,并且 ? 访问可选属性
const inputRef = useRef<HTMLInputElement>(null); const sureRef = useRef<HTMLDivElement>(null); const body = document!.getElementsByTagName("body")[0]; body.addEventListener("click", () => { console.log(sureRef.current?.style); console.log("body"); });
导入一个组件需要的多个类型
// userInterfence.ts export type UserInfo = { name: string; age: number; }; export type Menu = { title: string; price: number; isChecked: boolean; items: Array<{ name: string; price: number; }>; };
在另外一个组件引入
import type { UserInfo, Menu } from "./userInterfence"; const Input: React.FC<InputProps> = (props) => { const [userInfo, setUserInfo] = useState<UserInfo>({ name: "Web技术学苑", age: 10, }); const inputRef = useRef<HTMLInputElement>(null); const sureRef = useRef<HTMLDivElement>(null); const body = document!.getElementsByTagName("body")[0]; body.addEventListener("click", () => { console.log(sureRef.current?.style); console.log("body"); }); return ( <> <input type="text" ref={inputRef} value={userInfo.name} /> <input type="text" value={userInfo.age} /> <div ref={sureRef} onClick={props?.onSure}> 确定 </div> </> ); };
选择一个组件的指定的几个属性
在两个类似的组件,我们有一些公用的属性,此时我们的类型可以借用 Omit 去掉一些不需要的属性类型
import type { UserInfo, Menu } from "./userInterfence"; const MenuComp: React.FC<Omit<Menu, "items" | "isChecked">> = (props) => { return ( <> <p>{props.price}</p> <p>{props.title}</p> </> ); };
在 header 组件中引入
<header className={`App-header ${className}`}> <MenuComp price={10} title={"menuA"} /> {props.children} </header>
或者你可以使用 Pick 来选择指定的属性
import type { UserInfo, Menu } from "./userInterfence"; const MenuSubComp: React.FC<Pick<Menu, "items">> = (props) => { return ( <> <p>{props.items[0].name}</p> <p>{props.items[0].price}</p> </> ); };
另一个组件中使用
const Index: React.FC<Partial<Props>> = (props) => { const { className } = props; const subInfo: Pick<Menu, "items"> = { items: [ { name: "Web技术学苑", price: 10, }, ], }; return ( <header className={`App-header ${className}`}> <MenuComp price={10} title={"menuA"} /> <MenuSubComp items={subInfo.items} /> {props.children} </header> ); };
总结
在 react 高频常用的 ts ,比如如何申明一个组件的返回的类型,以及接收 props 的参数
如何申明一个dom上的类型,以及如何传入一个函数到子组件的类型
! 与 ? 的使用,当我们知道一定有该属性时,你可以使用 ! ,如果一个属性是可选的那么就用 ?
Omit 与 Pick 在组件中的使用,更多 typescript 参考官方文档学习
本文 code example
以上就是react常见的ts类型实践解析的详细内容,更多关于react常见的ts类型的资料请关注其它相关文章!
原文地址:https://juejin.cn/post/7222310732292898875
查看更多关于react常见的ts类型实践解析的详细内容...