DEV Community

Pan Chasinga
Pan Chasinga

Posted on

Reactive Props in Functional React

When I was learning React, the first distinction I remembered was between state and props. States are reactive, meaning they can be mutated and change how the UI becomes as the enclosing component re-renders. Props, on the other hand, are static, immutable properties a component acquires on mounting.

In the old Angular world I came from, I could do something like this:


<Component message={message} />

Enter fullscreen mode Exit fullscreen mode

And internally, I could bind to this message as it changed from the enclosing context and make changes inside Component. This "portal" is a mean by which the outer context can interface with the otherwise encapsulated component, like a puppet being controlled by a puppeteer.

So when I learn that with a functional React component, I could do the same, I was pretty surprised. For example, to toggle a component "on" and "off", instead of doing this:


{ visible ? <Component /> : null }

Enter fullscreen mode Exit fullscreen mode

I could implement Component in a way that it accepts visible as a prop and decide if it renders inside the component:


const Component = ({ show }) => {
  return show ? <h1>Hello, world</h1> : null;
};

Enter fullscreen mode Exit fullscreen mode

and use it this way instead:


<Component show={visible} />

Enter fullscreen mode Exit fullscreen mode

Which I find much cleaner than the bracket evaluation because the interface is kept within the component. For example, instead of a simple visibility toggle, I could add a delay to the component showing and hiding, and this new feature will be implemented everywhere I use Component:


const Component = ({ show, delay }) => {
  let timer = null;
  const [visible, setVisible] = useState(!show);

  // Whenever `show` changes, call setTimer that delays
  // the setting of `visible`.
  useEffect(() => {
    setTimer();
  }, [show]);

  function setTimer() {
    // clear any existing timer
    if (timer != null) {
      clearTimeout(timer)
    }

    // hide after `delay` milliseconds
    timer = setTimeout(() => {
      setVisible(!visible);
      timer = null;
    }, delay);
  }

  return visible ? (
    <h1>Hello, world</h1> 
  ) : null;
};

// use

<Component show={visible} delay={300} />

Enter fullscreen mode Exit fullscreen mode

This is probably not a big deal for elite React users, but for someone new like me, it's just awesome. I can't be 100% sure if this works in class-based component too.

Anyone know about this?


If you're interested in my non-programming thoughts, you can subscribe to my newsletter BETA School.

Joe Chasinga Newsletter BETA School

Top comments (1)

Collapse
 
miketalbot profile image
Mike Talbot ⭐ • Edited

Yeah that's nice. React writing JS from JSX and what that means is mind bending to start with!

Just for reference you could write your return as:

   return visible &&  <h1>Hello, world</h1> 
Enter fullscreen mode Exit fullscreen mode

Presuming visible can only be true of false. If it could be "falsey" then:

   return !!visible &&  <h1>Hello, world</h1> 
Enter fullscreen mode Exit fullscreen mode

Also of course you could make it a wrapper around children - and then have a generic one if you prefer it to the inline syntax (and still do your delays etc)

function Showable({show, children}) {
     return !!show && children
}
Enter fullscreen mode Exit fullscreen mode