About the best practice

Think in a Nullable world

Most of the data initial type is null in the codebase

// Don't
const foo = useState("")

// Do
const foo = useState<Nullable<string>>(null)

Prefer don’t use Optional chaining

// Don't 
const foo = ais?.data?.map(ai => ai.state) || []

// Do
const foo = useMemo(() => {

  // If you are using react-query, isSuccess will guarantee data
  if (!ais.isSuccess) return

  return ais.data.map(ai => ai.state)
}, [ais.isSuccess, ais.data])

Prefer inferred types over explicit ones

// Instead of doing

const item = React.useMemo<number>(() => {
	return 10
}, [])

// Do
const item = React.useMemo(() => {
	return 10
}, [])

Prefer early returns

// Instead of doing
const item = React.useMemo(() => {
	if (state.isSuccess){
		return state.data
  } else {
	  return null
  }
}, [])

// Do
const item = React.useMemo(() => {
	if (!state.isSuccess){
		return null
  } 

	return state.data
}, [])

Validate using zod instead of type casting

// Instead of doing
type DeploymentCreateBody = {
  deploymentName: string,
  deploymentType: "CLOUD" | "SELFHOSTED",
}

const { deploymentName, deploymentType } = req.body as DeploymentCreateBody;

// Do
const deploymentCreateSchema = z.object({
  deploymentName: z.string().min(1),
  deploymentType: z.nativeEnum(DeploymentType),
});

const { deploymentName, deploymentType } = deploymentCreateSchema.parse(req.body);

Align with the type of backend protobuf

Backend’s protobuf is our single source of truth. We should not only align with the type, we should also follow its naming (Ultimately, we will generate all the type from protobuf in the future)

Explicit over simplicity when it comes to naming

Please don’t hesitate to give a long name if it can explain the function or variable will!

Avoid Prop Drilling → Prefer compound components

https://twitter.com/asidorenko_/status/1623751929863016450?ref_src=twsrc^tfw|twcamp^tweetembed|twterm^1623751929863016450|twgr^ed675970eb813aa60936ccad775194a69a61b137|twcon^s1_&ref_url=https://cdn.iframe.ly/N2vg5zv?app=1

Prefer ternaries over Short Circuiting “&&” for React Components