Next.js: Converting JS components to TSX components
In this post, I wanted to walk you through converting your React JS components to TSX components.
Next.js has made it very easy to setup and incrementally adopt TypeScript. To get started, at the root of your project directory create a file named tsconfig.json
Head over to your terminal and run the following commands:
yarn add --dev typescript @types/react @types/node
yarn run dev
This will install the dependancies and populate your tsconfig.json
file for you. Let’s jump into the code.
/components/card.js
const Card = (props) => {
return (
<div onClick={props.handleClick}>
<img src={props.imgURL} alt={props.imgTitle} />
<h1>{props.title}</h1>
<p>{props.excerpt}</>
<p>{props.likes}</p>
</div>
)
}
First things first, rename the component to have a .tsx
file extension name. Next we need to define the props the component is receiving through what TypeScript calls interface
. Then we need to specify that the card component is a React Functional Component.
/components/card.tsx
interface CardProps {
imgUrl: String;
imgTitle: String;
title: String;
excerpt: String;
likes: Number;
handleClick: () => void;
}const Card: React.FC = (props) => {
return (
<div onClick={props.handleClick}>
<img src={props.imgURL} alt={props.imgTitle} />
<h1>{props.title}</h1>
<p>{props.excerpt}</>
<p>{props.likes}</p>
</div>
)
}
Now, instead of passing the component props
, let’s pass the component the interface we built then destructure the props.
interface CardProps {
imgUrl: String;
imgTitle: String;
title: String;
excerpt: String;
likes: Number;
handleClick: () => void;
}const Card: React.FC<CardProps> = ({ imgUrl, imgTitle, title, excerpt, likes, handleClick }) => {
return (
<div onClick={props.handleClick}>
<img src={props.imgURL} alt={props.imgTitle} />
<h1>{props.title}</h1>
<p>{props.excerpt}</>
<p>{props.likes}</p>
</div>
)
}
Since we have destructured the props being passed to it, we no longer need to interpolate the props variable.
interface CardProps {
imgUrl: String;
imgTitle: String;
title: String;
excerpt: String;
likes: Number;
handleClick: () => void;
}const Card: React.FC<CardProps> = ({ imgUrl, imgTitle, title, excerpt, likes, handleClick }) => {
return (
<div onClick={handleClick}>
<img src={imgURL} alt={imgTitle} />
<h1>{title}</h1>
<p>{excerpt}</>
<p>{likes}</p>
</div>
)
}
TypeScript and useState
Another item worth mentioning is using TypeScript with the React hook useState
. The declarative syntax with the hook can be quite helpful. To implement all you need to do is the following:
const [clicked, handleClick] = useState<boolean>(false)
const [incrementClicks, handleIncrementClicks] = useState<number>(0)
const [formData, setFormData] = useState<any>({
email: "",
password: ""
})const [data, setData] = useState<any[]>([])
const [nums, setNums] = useState<number[]>([])