从React.FC作为切入,谈谈学习在React中用TypeScript
• • ☕️ 2 min read你可以从本文了解到
- React.FC 是什么?和normal functions type 的区别是什么?
- 如何学习在React中使用TypeScript?
React.FC vs normal functions type
1 React.FC 始终隐含可以传入 children
React.FC等价于React.FunctionComponent。
从这一点日常便利性上看,React.FC优于normal functions type。
以下FC代码,一切正常,允许传入children
import React, { Component, FC } from "react";import { render } from "react-dom";
type GreetingProps = {
name: string;
};
export const Greeting:FC<GreetingProps> = ({ name }) => { // name is string! return <h1>Hello {name}</h1>};// use it in the app
const App = () => <React.Fragment>
<Greeting name="Stefan">
<span>{"I can set this element but it doesn't do anything"}</span>
</Greeting>
</React.Fragment>
render(<App />, document.getElementById("root"));
但下面这样写就要出现错误提示了。
Type '{ children: Element; name: string; }' is not assignable to type 'IntrinsicAttributes & GreetingProps'.
Property 'children' does not exist on type 'IntrinsicAttributes & GreetingProps'.(2322)
import React, { Component, FC } from "react";
import { render } from "react-dom";
type GreetingProps = {
name: string;
};
function Greeting({ name }: GreetingProps) {
return <h1>Hello {name}</h1>
}
// use it in the app
const App = () => <React.Fragment>
<Greeting name="Stefan">
{/* throws errors at me! 💥*/}
<span>{"I can set this element but it doesn't do anything"}</span>
</Greeting>
</React.Fragment>
render(<App />, document.getElementById("root"));
我们得做一些扩展,如下WithChildren部分,通过运算,并上了children属性。
import React, { Component, FC } from "react";
import { render } from "react-dom";
type WithChildren<T = {}> =
T & { children?: React.ReactNode };
type GreetingProps = WithChildren<{
name: string;
}>;
function Greeting({ name }: GreetingProps) {
return <h1>Hello {name}</h1>
}
// use it in the app
const App = () => <React.Fragment>
<Greeting name="Stefan">
<span>{"I can set this element but it doesn't do anything"}</span>
</Greeting>
</React.Fragment>
render(<App />, document.getElementById("root"));
2 React.FC 不支持 defaultProps
但是这边提到defaultProps不建议使用,即将废弃。 从这一点长期来看,React.FC还是优于normal functions type。
看下面这段代码,ts 会提示
Property 'name' is missing in type '{}' but required in type 'GreetingProps'.(2741)
import React, {Component, FC} from 'react';
import {render} from 'react-dom';
type GreetingProps = {
name: string;
};
export const Greeting: FC<GreetingProps> = ({name}) => {
// name is string!
return <h1>Hello {name}</h1>;
};
Greeting.defaultProps = {
name: 'World'
};
const App = () => (
<React.Fragment>
{/* boom 💥*/}
<Greeting />
</React.Fragment>
);
render(<App />, document.getElementById('root'));
而改成正常的type声明,如下所示,就pass了
import React, { Component, FC } from "react";
import { render } from "react-dom";
type GreetingProps = {
name: string;
};
export const Greeting = ({ name }:GreetingProps) => {
// name is string!
return <h1>Hello {name}</h1>;
};
Greeting.defaultProps = {
name: "World"
};
const App = () => (
<React.Fragment>
{/*✅*/}
<Greeting />
</React.Fragment>
);
render(<App />, document.getElementById("root"));
如何学习在React中使用TypeScript?
typescript-cheatsheets/react是一个很好的起点和手册查询地方。
本文只是抛砖引玉,之后有什么有意思的点,还会case by case的讨论学习。