paul23
paul23

Reputation: 9425

useRef in a dynamic context, where the amount of refs is not constant but based on a property

In my application I have a list of "chips" (per material-ui), and on clicking the delete button a delete action should be taken. The action needs to be given a reference to the chip not the button.

A naive (and wrong) implementation would look like:

function MemberList(props) {
    const {userList} = this.props;
    refs = {}
    for (const usr.id of userList) {
        refs[usr.id] = React.useRef();
    }

    return <>
        <div >
            {
                userList.map(usr => {
                    return <UserThumbView
                        ref={refs[usr.id]}
                        key={usr.id}
                        user={usr}
                        handleDelete={(e) => {
                            onRemove(usr, refs[usr.id])
                        }}
                    />
                }) :
            }
        </div>
    </>
}

However as said this is wrong, since react expects all hooks to always in the same order, and (hence) always be of the same amount. (above would actually work, until we add a state/any other hook below the for loop).

How would this be solved? Or is this the limit of functional components?

Upvotes: 2

Views: 894

Answers (1)

Kaca992
Kaca992

Reputation: 2267

Refs are just a way to save a reference between renders. Just remember to check if it is defined before you use it. See the example code below.

function MemberList(props) {
  const refs = React.useRef({});

  return (
    <div>
      {props.userList.map(user => (
        <UserThumbView
          handleDelete={(e) => onRemove(user, refs[user.id])}
          ref={el => refs.current[user.id] = el}
          key={user.id}
          user={user}
        />
      })}
    </div>
  )
}

Upvotes: 1

Related Questions