Skip to content
    SeaCode
    Learning tracksCode ArenaWorkshops & EventsInstructors
    Log inSign up
    ⚛React

    Components and JSX

    • Why React?
    • JSX rules
    • Props
    • Rendering lists and keys
    • Conditional rendering

    State and events

    • Handling events
    • useState: a component's memory
    • Objects and arrays in state
    • Forms and controlled inputs
    • Lifting state up

    Effects and essential hooks

    • useEffect
    • Fetching data
    • useRef
    • Context: data for the whole tree
    • useReducer

    Professional React

    • Writing your own hooks
    • Performance: memo, useMemo and useCallback
    • Suspense and error boundaries
    • What's new in React 19
    • Thinking in React
    • Project: a complete to-do app
    React

    Professional React · Lesson 16 of 21

    Writing your own hooks

    Pull repeated logic into a use… function and reuse it anywhere.

    9 minutes2 games

    If the same useState + useEffect keep repeating across components, extract them into a custom hook: a plain function whose name starts with use and which calls hooks. Each component using it gets its own copy of the state, so hooks share logic, not data.

    React
    function useToggle(initial = false) {
      const [on, setOn] = useState(initial)
      const toggle = useCallback(() => setOn((v) => !v), [])
      return [on, toggle]
    }
    
    function useWindowWidth() {
      const [width, setWidth] = useState(window.innerWidth)
      useEffect(() => {
        const onResize = () => setWidth(window.innerWidth)
        window.addEventListener("resize", onResize)
        return () => window.removeEventListener("resize", onResize)
      }, [])
      return width
    }
    
    function App() {
      const [menu, toggleMenu] = useToggle()
      const [dark, toggleDark] = useToggle(true)
      const width = useWindowWidth()
      return (
        <div>
          <p>Preview width: {width}px ({width < 500 ? "phone" : "wide"})</p>
          <button onClick={toggleMenu}>Menu: {menu ? "open" : "closed"}</button>
          <button onClick={toggleDark}>Theme: {dark ? "dark" : "light"}</button>
        </div>
      )
    }
    • useToggle() (one piece of logic)
      • App → menu: its own state
      • App → dark: its own state

    The same hook called twice; each call has separate state.

    Important

    A hook's name must start with use: that's how React and the linter know to apply the rules of hooks. If the function calls no hooks, don't name it use…; keep it a plain function.

    Complete the code

    Complete the hook that returns an input's value and its handler.

    function Input(initial) {
      const [value, setValue] = (initial)
      return { value, onChange: (e) => setValue(e.target.value) }
    }
    
    function App() {
      const name = useInput("")
      return <input {...name} />
    }

    Interview question

    How does a custom hook differ from a component, and from a plain utility function?

    Exercise

    Write useCounter(start) returning { count, inc, reset }, and use it twice independently in App: Likes from 0 and Stars from 10. The checker presses Likes twice and Stars once.

    The page should show: Likes 2 Stars 11

    React
    function useCounter(start) {
      return { count: start, inc: () => {}, reset: () => {} }
    }
    
    function App() {
      const likes = useCounter(0)
      const stars = useCounter(10)
      return (
        <div>
          <button className="likes" onClick={likes.inc}>Likes {likes.count}</button>
          <button className="stars" onClick={stars.inc}>Stars {stars.count}</button>
        </div>
      )
    }

    Learn more from

    • react.dev: Reusing logic with custom hooksreact.dev
    • react.dev: Rules of Hooksreact.dev
    • usehooks.com: a collection of custom hooksusehooks.com

    Played 0 of 2 games

    Sign in to save your progress and earn XP.

    PrevioususeReducerNextPerformance: memo, useMemo and useCallback
    SeaCode

    Learn to code for real, online or at our branch in front of Cairo University, Giza.

    Learn

    • All courses
    • Interactive tutorials
    • Interview practice problems
    • Mock interview
    • Learning tracks
    • Code Arena
    • Workshops & Events
    • Knowledge library
    • Team projects

    Your account

    • Log in
    • Sign up
    • Learning plan
    • Certificates
    • Site map

    Contact us

    • WhatsApp
    • 010 9094 1104
    • In front of Cairo University, Giza

    © 2026 SeaCode. All rights reserved.