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