React Hooks are one of the most important features in the React release. The style of functional components, the easy-to-manage business Hooks package, and the performance benefits of the Hooks. As the technology stack changes, writing React Hooks components in TypeScript is a bit of a challenge. Here are some practical lessons.

Type values

React.FC

React provides a type called FunctionComponent, which defines the type of the component. It can be shortened to React.FC.

JS version:

import React from 'react'

const Header = ({msg}) = > {
  return (
    <div>
      {msg}
    </div>)}export default Header
Copy the code

TSX version:

import React from 'react'

const Header: React.FC = ({msg}) = > {
  return (
    <div>
      {msg}
    </div>)}export default Header
Copy the code

Props

indicates that FC also supports typing a generic to specify the value of the Props property. By default, leaving it blank means that the component does not accept Props.

You can see in the code that we actually need to receive onemsgSo let me write it this wayIDEThere will definitely be an error, so you need to change it to the following:

import React from 'react'

const Header: React.FC<{msg: string} > =({msg}) = > {
  return (
    <div>
      {msg}
    </div>)}export default Header
Copy the code

Alternatively, an interface can be used to specify the props type value. In practice, it is recommended to use the interface to define the object type:

// ...
interface Props {
  msg: string;
}
const Header: React.FC<Props> = ({msg}) = > {
// ...
Copy the code

Once the Props interface type values are defined, it is convenient to get code prompts on the component’s input parameters.

useState

UseState provides state management capabilities for functional components, but defining a type for useState cannot be defined in the same way as defining a variable type. The type definition requires passing in a generic type:

const [count, setCount] = useState<number | null> (0)
Copy the code

If no incoming type, useState can automatically count support is deduced according to the initial values of type is number, but the incoming < number | null > later, call setCount when they need to pay attention to the into the type of the refs.

Such as:

setCount((count as number) + 1)
Copy the code

The input parameter of setCount may be number or NULL, so the type assertion needs to use the AS keyword, and count can be set to number for addition and subtraction operations.

After defining a type, other members of the team will be prompted to modify the code, ensuring that the code is robust.

useRef

UseRef is often used to retrieve the context of child component elements within functional components or to maintain a persistent state of the component (regardless of its life cycle), so it is also used frequently. The definition type for useRef is similar to that of useState, except that it requires different type values for different elements.

Hover over the elementrefOn,ideWill promptrefThe type of this property is acceptablestring, for refsHTMLButtonElementInstance ornullFunction, passed in the generic typeHTMLButtonElementRefObject,null , undefined. It can be inferred from the information herebtnRef.currentShould be of typeHTMLButtonElement 。

const btnRef = useRef<HTMLButtonElement>(null)
Copy the code

If the element is different, the ref type value will change with it, such as HTMLDivElement, HTMLInputElement, etc.

If useRef were used for component state, it would be used just like useState.

const numRef = useRef<number> (0)
numRef.current += 1     // corrent
numRef.current = 'test' // wrong
Copy the code

useReducer

UseReducer is another type of state management hooks that are already familiar with TypeScript. Redux.

interface Item {
  id: number;
  text: string;
}

type State = Item[]

type Actions = {
  type: 'add';
  text: string;
} | {
  type: 'remove';
  id: number;
}

const ItemReducer = (state: State, action: Actions) = > {
  switch(action.type) {
    case 'add':
      return [...state, {
        id: state.length + 1.text: action.text
      }]
    case 'remove':
      return state.filter(item= >item.id ! == action.id)default:
      return state
  }
}

// ----- Component splitter -----
const [items, dispatch] = useReducer(ItemReducer, [])
// ----- Component splitter -----
Copy the code

First of all, we need to define the input parameter types of reducer. Here we have defined the input parameter types of state and action. State is a list of item types, and action has several fixed call modes.

This is called in the componentdispatch“Will promptdispatchWhat parameters are received:

The interface group is used to define the type of Object data, while the type keyword deals with complex types:

type StringOrNumber = string | number;  
type Text = string | { text: string };  
type NameLookup = Dictionary<string, Person>;  
type Callback<T> = (data: T) = > void;  
type Pair<T> = [T, T];  
type Coordinates = Pair<number>;  
type Tree<T> = T | { left: Tree<T>, right: Tree<T> };
Copy the code

Tip 💡

While TypeScript brings strong type checking, it also takes some effort to regulate component and variable types, so here’s a tip to improve productivity on a daily basis.

Start by openingvscodePreferences, and then click on the User segmentThen entertypescriptreact.json, click the following prompts to enter the setting interface

Configure the following JSON

{
  "Init Template": {
    "prefix": "rtfc"."body": [
      "import React from 'react'".""."const Component: React.FC
      
        = () => {"
      .""." return ("." 
      
"
." init txt"." ".")"."}"]."description": "init tempalte for tsx"}}Copy the code

Save the Settings and create a new oneindex.tsxAnd then typertfcEnter ok

The body content from the previous JSON configuration appears on the page, although the content of the body can be set by the developer

The “user fragment” here is a handy way to customize hints for different file typesTypeScriptDeveloper type Settings.

The end of the

Incorporating typescript is the future of the front end, and there are plenty of good typescript tutorials out there.

PS: If there are any mistakes in this article, please kindly correct them

Past wonderful 📌

  • React DevTools ✨
  • Vue3 hugs TypeScript properly ✨
  • Vue3-one piece尝鲜:React Hooks VS Composition API ✨
  • Optimize performance ✨

🏆 nuggets technical essay | double festival special articles