wkrueger
wkrueger

Reputation: 1363

React Hooks - How to avoid redeclaring functions on every render

On a react class I would write something like this

class Myclass extends React.Component {
  handleUpdate = info => {
    //do the update
  }

  render() {
    return (
      <SomeMarkup>
        <SomeComponent onUpdate={this.handleUpdate} />
      </SomeMarkup>
    )
  }
}

If using a function I could just write the following

function MyFunction() {
  function handleUpdate(info) {
    // do the update
  }
  return (
    <SomeMarkup>
      <SomeComponent onUpdate={handleUpdate} />
    </SomeMarkup>
  )
}

...but with that I'd be redeclaring a function on every render. Is there any sort of trick that would memoize the handler function between renders? Or should I just move the handler out of the render scope? (Moving it out of the render scope requires me that I explicitly pass more parameters since I wont directly have access to the function scope.)

Upvotes: 13

Views: 5855

Answers (2)

vibhay mall
vibhay mall

Reputation: 1

const UserList = ({ user, deleteUser }) => {
  return (
    <div className='user'>
      <div className='user-details'> {user}</div>
      ....
      <hr />
      <button onClick={() => deleteUser(user)}>Delete User</button>
    </div>
  )
}

const Users = () => {
  const [users, setUser] = useState([1, 2, 4, 5, 6]);
  const [count, setCount] = useState(0);

  const onHandleMouseLeave = () => {
    setCount(count => count + 1)
  }
  console.log("Mouse was entered no of time: ",count)

  const deleteUser = useCallback((id) => {
    const usersToBeUpdate = users.filter(user => user !== id);
    setUser([...usersToBeUpdate])
  }, [])
  return (
    <div>
      Users
      <div className='list-user' onMouseLeave={onHandleMouseLeave}>
        {users.map((user, i) =>
          <UserList user={user} deleteUser={deleteUser} />
        )}
      </div>
    </div>
  )
}

Upvotes: -1

Ryan Cogswell
Ryan Cogswell

Reputation: 80996

This is exactly the scenario that useCallback is for. The function still gets declared every time with useCallback, but the function returned is memoized so that if it is passed as a property to children, the children will receive a consistent function unless it has to change due to dependencies changing.

Please see my recent related answer here that demonstrates in detail how useCallback works: Trouble with simple example of React Hooks useCallback

Here's another related answer: React Hooks useCallback causes child to re-render

Upvotes: 8

Related Questions