How can i define a function oustide my sfc component

My code

const DrumButtonItem = props => {
  const play = () => {
    audio.current.play();
  };
  const audio = React.useRef();

  const { keyTrigger, url } = props.drum;

  return (
    <div onClick={play}>
      {keyTrigger}
      <audio src={url} ref={audio} />
    </div>
  );
};

export default DrumButtonItem;

I want to declare play function outside the DrumButtonItem component. How can i do it. ??

If i declare it outside it gives me an error, due to scope i guess(not sure)!!

Thanks

Hello there.

The common thing to do is declare the function in your parent component, then pass the function as a prop to the child.

Okay so I did what you said, and my onClick is not working anymore.

I have passed play function as a prop, still it is not working . Why ??

DrumButtons is parent component.
DrumButtonItem is child

let audio = null;

const play = () => {
  // UPDATE
  audio.current && audio.current.play();
};

const DrumButtonItem = props => {
  
  audio = React.useRef(null);

  const { keyTrigger, url } = props.drum;

  return (
    <div onClick={play}>
      {keyTrigger}
      <audio src={url} ref={audio} />
    </div>
  );
};

Why do you need it? This is quite hacky

Your play function uses audio ref that was defined inside component. You can pass something like this:

const play = (audio) => audio.play();

// and then

onClick={() => play(audio.current)}

…but that’s seems to be pointless

Yes your solution works too. I was trying to pass play and audio as prop to DrumButtonItem.
I have few questions

  1. Does passing a ref variable (initialized using React.useRef(null); )as prop causes some issue or it is not a good practice?

  2. Why do you pass null to useRef ?

  3. Why do you use audio && audio.current.play(); not just audio.current.play(); ?

You can pass ref and it should not cause any issues. It’s generally an imperative technique when your component will depend on the state of other component and goes sort of against React believes :slight_smile: but if there’s no other solution, then what can you do, right?

It’s just a matter of personal preference, in DOM when there’s no node found browser normally returns null and not undefined.

Because audio could be null (or undefined in your case). You can also use optional chaining like that:

audio?.current?.play();
1 Like

Also note, that there was a typo: audio will most likely exist, the check supposed to be against audio.current, I’ve updated my post to reflect that

1 Like