- Component functions must follow two rules: the name starts with an uppercase letter and it returns something that can be rendered (JSX, a string, etc).
{}
inside a component means you want to render a dynamic value.
- You can include images using the
import imageName from ‘./path/img.png’;
syntax.
useState
is a React hook - everything starting with use
is a hook.
- Hooks can only be called inside components.
- Prop drilling: passing shared data through multiple layers of components.
- When you want a component to “remember” some information, but you don’t want that information to trigger new renders, you can use a
ref
. It is like a static variable.
- Context API facilitates sharing data and can be connected to state.
- They are usually stored in a
store
folder.
const CartContext = createContext({items: []})
is used to create the context.
- You then wrap your components into
<CartContext value={{items:[]}}><Header><Shop></CartContext>
- You can then import
CartContext
and useContext
to read from the context in the components you want. const cartCtxd = use(CartContext)
and cartCtx.items
to read the stored value.
- You can use a context component to provide the data in a more structured way, e.g.
export default const CartContextProvider({children}) { state, functions, etc; return <CartContext value={...}>{children}</CartContext>; }
- Reducers are functions that reduce one or more complex values to a simpler one.
useReducer
can be used to manage state.
const [ state, dispatch ] = useReducer(action, state)
where dispatch
is a function that will trigger an action function action(state, action)
.
- Side-effects in React are tasks that do not directly impact the components render cycle.
useEffect(() => { side effect method calls }, [dependencies])
wraps side-effects to prevent infinite loops.
useEffect
only executes after the component function is done execution, i.e. returned JSX.
- React only executes the effect again if some of the
dependencies
change. Having an empty array []
makes the effect function run only once, but it is usually not necessary if the side-effect is synchronous.
- Effects can be used to synchronize values with a DOM API or a certain value we need to use.
useCallback
is a hook that lets you cache a function definition between re-renders, and is useful when passing functions to useEffect
.
useEffect
can receive a clean function that is executed when a component is unmounted.
- Keep components small to avoid computing unnecessary times.
- Error boundary is a special component that can be used to propagate an error to a parent component when a child component crashes. It has to be implemented as a class component.
memo
can be used to memoize components to avoid unnecessary executions, unless their input arguments change. Don’t overuse it, because it has performance costs.
useCallback
can also be used to cache function definitions that are passed as arguments to child components.
useMemo
can be used to prevent a function being executed unless its input changes.
key
can be used to trigger component resets.
- Hooks may only be used inside of component functions or other hooks, and cannot be inside nested statements.
- Custom hooks must start with
use
.
- A hook can manage state too.
- On forms, listen to the
onSubmit
event on the form itself, i.e. <form onSubmit={}>
.
- To handle state, map either each individual field to its own state, or have a shared state object for all of them.
- You can reset a form via the
onSubmit
event by doing event.target.reset()
.
- Validation is done best combining
onKeyDown
and onBlur
, by checking whether or not the values changed.
- Form Actions let you use a
<form action={loginAction}>
form handler. The handler will receive an instance of FormData
and you will not need to call the preventDefault
function.
useActionState
allows you to update state based on the result of a form action. It returns some state, an action handler, and a “pending” state, which is useful for async handlers.
useFormStatus
can be used to provide status information of the last form submission. It only returns status information for a parent <form>
.
- The
formAction
prop can be used to set different actions for different buttons.
useOptimistic
lets you show a different state while an async action is underway. This state is called the “optimistic” state because it is usually used to immediately present the user with the result of performing an action, even though the action actually takes time to complete. It also rollbacks to the previous state if the action fails.
- React Router can be used for routing in SPAs.
- Use
createBrowserRouter
to create the routes of your application.
- Convention: add components that will be rendered via routing in the
pages
directory.
<Link to=”/somehwere”>
creates a SPA-friendly anchor, i.e. that does not trigger regular HTTP requests, but is internally handled. NavLink
is a replacement for Link
that can have an active state.
errorElement
can be used to display errors.
useNavigate
can be used to programmatically navigate an user to a different route.
useParams
lets you get the URL params. useSearchParams
lets you get the query params.
- Paths may be either relative or absolute.
<Link to=”..”>
goes back to the parent route.
index
in the route definition indicates a route is the default one.
loader
in the route definition triggers fetching data before a component is rendered. It can be used in the component via useLoaderData
. You can use any function inside of loader functions. When erroring, just throw { message: wrong }
or json({ message: ‘error’ }, { status: 500 })
and it will be caught by the closest errorElement
.
- A child component can use the loader from a parent component by using
useRouteLoaderData
.
useNavigation
can be used to give the user feedback when the page is loading.
action
in the route definition can be used to do data mutations. You can use these actions by using the Form
wrapper from react-router-dom
.
redirect
redirects!
useFetcher
is used to trigger actions without triggering router transitions.
- Suspense and Await can be used to load non-critical data in a non-blocking manner.
lazy
lets you defer loading component’s code until it is rendered for the first time.
use
is a React API that lets you read the value of a resource like a Promise or context.
- Debouncing is based on a utility function that delays the execution of a given function until a specified wait time has passed since the last invocation. This is useful in scenarios where events fire frequently, such as resizing, scrolling, or input events, helping prevent unnecessary or excessive function calls that can affect performance.
- TanStack Query: is an asynchronous state management library.
useQuery
will send requests and return the current state (pending, success, error).