Sarmad Shah
Sarmad Shah

Reputation: 3805

React: Custom Ref (Without DOM)

I have been using React from few years and today I encouraged a very unique use case which I need to tackle. I need to make my own ref. there are certain libraries that do it and I don't yet how they do it.

So basically what I need to do is

const ref = useRef();

/**
 where ref.reset(); will work
*/

<Menu ref={ref}/>

My custom component:


const Menu = () => {
  const reset = () => {
   setValue(0);
  }

 return <CustomMenuComponent />
}

So basically I need to expose this method in the parent. I know this can be done via state and should be done that way, I have just added a minimum use case for my problem. So basically I need to expose some methods in my component, ideally using refs.

Upvotes: 4

Views: 4394

Answers (2)

Dennis Vash
Dennis Vash

Reputation: 53914

Thats when useImperativeHandle used.

useImperativeHandle customizes the instance value that is exposed to parent components when using ref.

const Menu = React.forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    reset: () => {
      console.log("reset");
    }
  }));

  return <></>;
});

export default function App() {
  const ref = useRef();

  useEffect(() => {
    ref.current.reset();
  }, []);
  return <Menu ref={ref} />;
}

Edit epic-violet-78cc7

Upvotes: 15

Nicholas Tower
Nicholas Tower

Reputation: 85062

For that, there's the rarely-needed useImperativeHandle hook. It lets you specify what external components will get if they pass a ref into your function component:

const Menu = React.forwardRef((props, ref) => {
  const [value, setValue] = useState(0);

  useImperativeHandle(ref, () => {
    return {
      reset: () => setValue(0)
    }
  }, []);

  return <CustomMenuComponent />
});

// Usage:
const Example = () => {
  const ref = useRef();

  useEffect(() => {
    ref.current.reset();
  }, []);

  return <Menu ref={ref} />;
}

You can see more information on this hook here. As they mention in the docs, you should avoid using refs when possible, though you seem to be aware of this as you described yourself as having "a very unique use case".

Upvotes: 3

Related Questions