Rapid Prototyping Made Easy with React PowerPlug – HAPITECHS

Rapid Prototyping Made Easy with React PowerPlug

If you’re trying to rapid prototype an app the last thing you want to be doing is implementing the same state management logic over and over. Adding something like Redux can help but tends to just adds a layer of complexity that can slow you down every further. React PowerPlug makes rapid prototyping a breeze by introducing a set of stateful components that let you focus on the good stuff, actually prototyping!

React PowerPlug is a set of renderless components that provide different types of state management scenarios by way of render props. The project is dependency-free, well documented and pretty small at around 3kb.

A word of warning though, the project’s master branch is still considered unstable and under active development. I opted to talk about the unstable version because it has so much more to offer in terms of different types of stateful components.

Getting Started

To get things started, we will need to add React PowerPlug to our project:

Via npm

$ npm install --save react-powerplug 

Or via Yarn

$ yarn add react-powerplug 

With the dependency added to our project, we will need to import React PowerPlug in it’s entirety:

import ReactPowerPlug from "react-powerplug"; 

Or import the individual components we’d like to use:

import { Counter, Hover, Togggle } from "react-powerplug"; 


As mentioned, the master branch of this project has a ton of additional stateful components.

While the type of data may be different between the components, nearly all of the components accept an initial property to set the default state.

Managing State

A component’s state can come in many different forms. It could be as simple as holding a single value or as complex as a mixed bag of boolean values, counters and string values.


State is one of the more basic components. Very similar to React’s baked in state property, State allows you to maintain an object of state properties that can updated via setState:

<State initial={{ favorite: "", picked: "" }}>   {({ state, setState }) => (     <div>       <button         onClick={() =>           setState({             favorite: "Alligator",             picked: new Date().toLocaleTimeString()           })         }       >         Alligator       </button>       <button         onClick={() =>           setState({             favorite: "Crocodile",             picked: new Date().toLocaleTimeString()           })         }       >         Crocodile       </button>       <button onClick={() => setState({ favorite: "", picked: "" })}>         Reset       </button>       {state.favorite && state.picked && (         <div>           <br />You picked {state.favorite} at {state.picked}         </div>       )}     </div>   )} </State> 


Toggle is a component for maintaining the state of a boolean value:

<Toggle initial={false}>   {({ on, toggle }) => (     <div>       <input type="checkbox" checked={on} onChange={toggle} />       <br /><br />       {on && <div>This box is CHECKED!</div>}       {!on && <div>This box is NOT CHECKED!</div>}     </div>   )} </Toggle> 


Counter allows you to increment and decrement an integer in the state:

<Counter initial={0}>   {({ count, inc, dec }) => (     <div>       {count === 0 && <div>There are no little alligators</div>}       {count === 1 && <div>There is 1 little lonely alligator</div>}       {count > 1 && <div>There are {count} little alligators</div>}       <div>         <br />         <button onClick={dec}>-</button>         <button onClick={inc}>+</button>       </div>     </div>   )} </Counter> 


Value is for maintaining the state of a single value. Set it and forget it:

<Value initial="#008F68">   {({ value, set }) => (     <div>       <div         style={{           height: 100,           width: 100,           background: value,           margin: "0 auto"         }}       />       <div>         <br />         <button onClick={() => set("#008F68")}>#008F68</button>         <button onClick={() => set("#6DB65B")}>#6DB65B</button>         <button onClick={() => set("#4AAE9B")}>#4AAE9B</button>       </div>     </div>   )} </Value> 


The Map component is quite similar to State as it controls state as an object with different properties. Where it differs is that you interact with the state via get and set methods:

<Map initial={{ reptile: "", picked: "" }}>   {({ set, get }) => (     <div>       <button         onClick={() => {           set("favorite", "Alligator");           set("picked", new Date().toLocaleTimeString());         }}       >         Alligator       </button>       <button         onClick={() => {           set("favorite", "Crocodile");           set("picked", new Date().toLocaleTimeString());         }}       >         Crocodile       </button>       <button         onClick={() => {           set("favorite", "");           set("picked", "");         }}       >         Reset       </button>       {get("favorite") &&         get("picked") && (           <div>             <br />You picked {get("favorite")} at {get("picked")}           </div>         )}     </div>   )} </Map> 


Not to be confused with the aforementioned set method, the Set component manages it’s state as an array of values which you can add to and remove from:

<Set initial={["Alligator", "Crocodile"]}>   {({ values, add, remove }) => (     <div>       {values.length === 0 && <div>Our set is empty!</div>}       {values.length > 0 && (         <div>           {values.map(value => (             <div>               {value}&nbsp;               <button onClick={() => remove(value)}>X</button>               <br /><br />             </div>           ))}         </div>       )}       <input         type="text"         placeholder="Type here and hit enter"         onKeyPress={event => {           if (event.key === "Enter") {             add(event.target.value);             event.target.value = "";           }         }}       />     </div>   )} </Set> 


List also holds it’s state as an array. Instead of simple add and remove methods, you interact with the array via push and pull methods.

Considering the complexity that is introduced by needing to know the index of the array item when pulling from the state, I’d probably just stick to Set:

<List initial={["Alligator", "Crocodile"]}>   {({ list, push, pull }) => (     <div>       {list.length === 0 && <div>Our list is empty!</div>}       {list.length > 0 && (         <div>           {list.map(item => (             <div>               {item}&nbsp;               <button onClick={() => pull(i => item === i)}>X</button>               <br /><br />             </div>           ))}         </div>       )}       <input         type="text"         placeholder="Type here and hit enter"         onKeyPress={event => {           if (event.key === "Enter") {             push(event.target.value);             event.target.value = "";           }         }}       />     </div>   )} </List> 

Managing User Interactions

Keeping track of a user’s interaction with a component usually includes binding event handlers on top of keeping track of the current state. React PowerPlug does a great job of not only combining these implementations but also keeping you fairly insulated from needing to worry about event handlers.


Hover keeps track of whether or not a user is hovering over a component:

<Hover>   {({ hovered, bind }) => (     <div {...bind}>       {!hovered && <div>See you later, alligator!</div>}       {hovered && <div>After 'while, crocodile!</div>}     </div>   )} </Hover> 


Active knows if a user is clicking on a component:

<Active>   {({ active, bind }) => (     <div {...bind}>       {!active && <span>Click here to activate!</span>}       {active && <span>STOP CLICKING ME!!</span>}     </div>   )} </Active> 


Similar to Active, the Touch component is the touch-friendly equivalent:

<Touch>   {({ touched, bind }) => (     <div {...bind}>       {!touched && <span>Touch here to trigger!</span>}       {touched && <span>STOP TOUCHING ME!!</span>}     </div>   )} </Touch> 


Focus is perfect for showing and hiding information based on which field a user is currently interacting with:

<Focus>   {({ focused, bind }) => (     <div>       <input         type="text"         placeholder="Click to focus this input!"         {...bind}       />       <div>         {focused           ? "Great for showing help text ONLY when focused!"           : ""}       </div>     </div>   )} </Focus> 


Even though React PowerPlug has components that could easily be used to wrap up form components, they still took the time to include some form-specific components to help save you time:


Input, which works with input instead of replacing it, binds input events to an input or any form field and stashes the value in the state:

<Input initial="">   {({ bind, value }) => (     <div>       <input type="text" {...bind} />       <div>         {value.length           ? `You typed: ${value}`           : "You have not typed anything :("}       </div>     </div>   )} </Input> 


The Form component takes things a step further by allowing you to track the state of multiple fields on a form with ease:

<Form initial={{ firstName: "", lastName: "" }}>   {({ input, values }) => (     <form       onSubmit={e => {         e.preventDefault();         console.log("Form Submission Data:", values);       }}     >       <input         type="text"         placeholder="Your First Name"         {...input("firstName").bind}       />       <input         type="text"         placeholder="Your Last Name"         {...input("lastName").bind}       />       <input type="submit" value="All Done!" />     </form>   )} </Form> 


React PowerPlug isn’t just for tracking state variables and user input, you can also use it wire up components to update automatically.


Unlike the other components we’ve discussed, Interval doesn’t take an initial state value and instead takes delay (in milliseconds).

<Interval delay={1000}>   {({ start, stop, toggle }) => (     <div>       Updates every second, last updated at:{" "}       {new Date().toLocaleTimeString()}       <br /><br />       <div>         <button onClick={() => stop()}>Stop</button>         <button onClick={() => start()}>Start</button>         {" or "}         <button onClick={() => toggle()}>Toggle!</button>       </div>     </div>   )} </Interval> 


React PowerPlug stands up to the claims that it makes it easy to rapid prototype apps in React. As the project is very much a work in progress right now, I’m super excited to see where the team ends up taking it!

I hope that you enjoyed this run down of React PowerPlug and if you are interested in seeing the code samples in action, you can head over to CodeSandbox.

Leave a Reply

Your email address will not be published. Required fields are marked *