React Tips and Tricks

Tips and Tricks for new React developers.


React revolutionized the way people build user interfaces and handle state. I'll share some tips and lessons I've learned as a react developer.`

1. Destructuring Props

Destructuring was one of the more novel concepts to me as I learned javascript and react. I also find it extremely common, and important to understand.

// Before
const MyComponent = (props) => {
  return <div>{props.title}</div>;
};

// After
const MyComponent = ({ title }) => {
  return <div>{title}</div>;
};

## 2. Use map for Rendering Lists

Rendering lists of elements is a common task in React. Here, the map function can be used:

```jsx

const myList = [1, 2, 3, 4];

return (
<div>
    {myList.map((item) => <li key={item}>{item}</li>)}
</div>
)

3. Memoization with React.memo

Optimize your functional components by memoizing them with React.memo. This prevents unnecessary re-renders and boosts performance:

const MemoizedComponent = React.memo((props) => {
  // Component logic
});

Wrap your component with React.memo to memoize it and compare props before re-rendering.

4. useState Hook

useState allows functional components to manage state. Use it like this:

import React, { useState } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

If you're initial value requires intense computation, memoize the intial computation by passing a function into useState():

import React, { useState } from 'react';

const Component = () => {
  const [complexValue, setComplexValue] = useState(() =< {
    //time-consuming calculation
    return value;
  });

  return (
    <div>
      <p>Value: {value}</p>
    </div>
  );
};

5. useEffect Hook

useEffect handles 'side effects' in functional components. That just means whenever you need a function to change things outside of that function, like fetching data:

import React, { useState, useEffect } from "react";

const DataFetcher = () => {
  const [data, setData] = useState();

  useEffect(() => {
    // Fetch data and update state
    fetch("https://api.example.com/data")
      .then((response) => response.json())
      .then((result) => setData(result))
      .catch((error) => console.error("Error fetching data:", error));
  }, []); // Empty dependency array means this effect runs once after initial render

  return <div>{data ? <p>Data: {data}</p> : <p>Loading...</p>}</div>;
};

Add variables into the dependency array to re-run the effect every time the dependency variable updates:

import React, { useState, useEffect } from "react";

const DataFetcher = () => {
  const [data, setData] = useState();
  const [nameFilter, setNameFilter] = useState();

  useEffect(() => {
    // Fetch data and update state
    fetch(`https://api.example.com/data?name=${nameFilter}`)
      .then((response) => response.json())
      .then((result) => setData(result))
      .catch((error) => console.error("Error fetching data:", error));
  }, [nameFilter]);

  return (
    <div>
      {data ? (
        <p>
          Data with name {name}: {data}
        </p>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
};

6. useReducer Hook

useReducer is a powerful alternative to useState when dealing with complex state logic, or to turn many state variables into one reducer variable:

import React, { useReducer } from "react";

const initialState = { count: 0 };

const reducer = (state, action) => {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    // can add many more cases, more variables that 'count', and much more logic
    default:
      return state;
  }
};

const CounterWithReducer = () => {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: "increment" })}>Increment</button>
      <button onClick={() => dispatch({ type: "decrement" })}>Decrement</button>
    </div>
  );
};

7. useCallback and useMemo Hooks

useCallback and useMemo optimize performance by memoizing functions and values:

import React, { useCallback, useMemo } from "react";

const MemoizedComponent = ({ data }) => {
  const memoizedFunction = useCallback(() => {
    // Function logic
  }, [data]); // Recreate the function only when 'data' changes

  const memoizedValue = useMemo(() => {
    // Value logic
    return someHeavyComputation(data);
  }, [data]); // Recreate the value only when 'data' changes

  return (
    <div>
      <p>Memoized Value: {memoizedValue}</p>
      <button onClick={memoizedFunction}>Do Something</button>
    </div>
  );
};

Conclusion

Learning best practices with react hooks will make your react apps much faster, readable, and will just make coding more enjoyable.

Happy coding!