DEV Community

Aurora
Aurora

Posted on

Improve your callbacks by making their return meaningful

When dealing with the more interractive elements of React like inputs or buttons, you will often come across the need of passing around callbacks like this:

const MyInput = (props) => {
  return(
    <input
    type="text"
    value={props.value}
    onChange={props.onChange}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

And focusing on the onChange part of the snippet, it will call the callback with the values and that's about it, ignoring if it returns anything.

But with a need for making it easier to make stuff happen when pressing enter, I came up with the following snippet:

const MyInput = (props) => {
  return(
    <input
    type="text"
    value={props.value}
    onChange={props.onChange}
    onKeyDown={(e) => {
      if (e.key === 'Enter') {
        props.onEnter()
      }
    }}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

usually with the idea that I should make it blur sometimes when I press enter. And then I had the idea that props.onEnter() should return if it will stay focused or not, leading to the following idea:

const MyInput = (props) => {
  const inputRef = useRef(null);
  return(
    <input
    type="text"
    ref={inputRef}
    value={props.value}
    onChange={props.onChange}
    onKeyDown={(e) => {
      if (e.key === 'Enter') {
        const keepFocus = props.onEnter();
        keepFocus || inputRef.current.blur();
      }
    }}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

This way, whenever I need to use my custom MyInput component, I can write an elegant onEnter callback like this:

<MyInput
value={value}
onChange={setValue}
onEnter={() => {
  if (value === '') {
    return false;
  } else {
    process(value);
    setValue('');
    return true;
  }
}}
/>
Enter fullscreen mode Exit fullscreen mode

so that if the user presses enter when there is something in the input field, it will process it and clear it, keeping focus on it. But if it is empty, it will simply blur the input field.

A similar pattern can be found in React's useEffect hook, it's basic idea is that you just pass in a callback for what it should execute after each render, but if you need it to clean up, you make the callback return a cleanup function.

So the next time you make a component take a callback, consider if you can give your code more functionality by working with what it returns.

Top comments (2)

Collapse
 
nithish_13 profile image
Nithish Kumar

Good tutorial

Collapse
 
imsiaw profile image
Imsiaw

its very useful ❤️