theme | transition |
---|---|
white |
slide |
Tipps & Tricks
(... am I standing in front of you?)
- TypeScript is a common topic β¨
- React is very popular π€·ββοΈ
- Many ways, choices and problems π³
- Start with a simple project π°
- Look at a few common concepts
- Improve little by little π
- Learn along the way π§βπ
Choose your level of typescript.
- Just make your life easier
- Make team life easier
- Make code safer
- Typed all the way
Get more docs.
$ npm install \
@types/react \
@types/react-dom \
--save-dev
Use .jsx
with .tsx
No: "export default
"
import React from 'react'
import * as React from 'react'
- tsconfig.json
{ "compilerOptions": { "jsx": "react-jsx" } }
tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"target": "ES2020",
"lib": ["DOM", "ES2020"]
}
}
tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"target": "ES2020",
"lib": ["DOM", "ES2020"],
"moduleResolution": "NodeNext"
}
}
define the props
export const Main = ({ value }: { value: string }) =>
<div className="main">{value}</div>
extract to an interface
interface MainProps {
value: string
}
export const Main = ({ value }: MainProps) =>
<div className="main">{value}</div>
export it!
export interface MainProps {
value: string
}
export const Main = ({ value }: MainProps) =>
<div className="main">{value}</div>
Is it optional? Make it optional!
interface MainProps {
value?: string
}
export const Main = ({ value }: MainProps) =>
<div className="main">{value}</div>
Pass other properties as well!
type DivProps = React.DetailedHTMLProps<
React.HTMLAttributes<HTMLDivElement>,
HTMLDivElement,
>;
export interface MainProps extends DivProps {
value?: string
}
export const Main = (props: MainProps) => {
const { value, ...rest } = props
return <div className="main" {...rest}>{value}<div>
}
merge instead of override
$ npm install classnames --save
components/Main.tsx
import classNames from 'classnames'
type DivProps = React.DetailedHTMLProps<
React.HTMLAttributes<HTMLDivElement>,
HTMLDivElement,
>;
export interface MainProps extends DivProps {
value?: string
}
export const Main = (props: MainProps) => {
const { value, className, ...rest } = props
return <div
className={classNames('main', className)}
{...rest}
>{value}<div>
}
import { forwardRef } from 'react'
export const Main = forwardRef((props: MainProps, ref) => {
const { value, className, ...rest}
return <div
ref={ref}
className={classNames('main', className)}
{...rest}
>{value}</div>
})
import { forwardRef } from 'react'
export const Main = forwardRef<HTMLDivElement>(
(props: MainProps, ref) => {
const { value, className, ...rest}
return <div
ref={ref}
className={classNames('main', className)}
{...rest}
>{value}</div>
}
)
export interface MainProps {
children: string
}
export const Main = ({ children }: MainProps) => {
return <div className='main'>{children}<div>
}
export interface MainProps {
children: string | string[]
}
export const Main = ({ children }: MainProps) => {
return <div className='main'>{children}<div>
}
types.d.ts
export type OneOrMany <T> = T | T[]
component/Main.tsx
import type { OneOrMany } from '../types.d.ts'
export interface MainProps {
children: OneOrMany<string>
}
export const Main = ({ children }: MainProps) => {
return <div className='main'>{children}<div>
}
types.d.ts
export type OneOrMany <T> = T | T[]
component/Main.tsx
import type { OneOrMany } from '../types.d.ts'
import { Children } from 'react'
export interface MainProps {
children: OneOrMany<string>
}
export const Main = ({ children }: MainProps) => {
return <div className='main'>{
Children(children).join('')
}<div>
}
$ npm install \
typescript \
--save-dev
Easy to miss!
- (in ts file)
Cmd
+P
- "
> TypeScript: Select TypeScript Version...
" - "
Use Workspace Version
"
.vscode/settings.json
{
"typescript.tsdk": "./node_modules/typescript/lib"
}
π
interface Project {
id: string,
name: string,
data: any,
}
export const ProjectDisplay = ({ project }: ProjectDisplayProps) => {
return <div className="project-display">
</div>
}
(bad, but a good start)
import { useEffect, useState } from 'react'
export const Events = () => {
const [state, setState] = useState<any>()
useEffect(
() => {
fetch('https://owddm.com/public/events.json')
.then(res => res.json())
.then(data => setState({
data,
success: true
}))
},
[]
)
return <></>
}
npm i swr
util/fetchJSON.ts
async function fetchJSON(url: string) {
return await (await fetch(url)).json()
}
component/Events.tsx
import useSWR from 'swr'
export const Events = () => {
const data = useSWR(
'https://owddm.com/public/events.json',
async url => await fetchJSON(url)
)
return <ul className="events">{
data.data?.venues.map(venue =>
<li key={venue.id}>{venue.name}</li>
)
}</ul>
}
util/fetchJSON.ts
async function fetchJSON(url: string) {
return await (await fetch(url)).json()
}
component/Events.tsx
import useSWR from 'swr'
export const Events = () => {
const data = useSWR(
'https://owddm.com/public/events.json',
async url => await fetchJSON(url)
)
return <ul className="events">{
data.data?.venues.map(venue =>
<li key={venue.id}>{venue.name}</li>
)
}</ul>
}