Categories
React Tips

React Tips — styled-components, Batch Updates, Child Validation

Spread the love

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

React Batch State Update Batching with Hooks

If the state changes and triggered asynchronously, then they won’t be batched.

On the other hand, if they’re triggered directly, then they’ll be batched.

For instance, if we call multiple state change functions within a promise, then they won’t be batched:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function Component() {
  const [foo, setFoo] = useState('a');
  const [bar, setBar] = useState('b');

  const handleClickPromise = () => {
    Promise.resolve().then(() => {
      setFoo('aa');
      setBar('bb');
    });
  }

  return (
    <>
      <button onClick={handleClickPromise}>
        click me
      </button>
      <p>{foo} {bar}</p>
   </>
  );
}

If the state change functions are called in a promise as we have in the then callback, then they won’t be batched.

On the other hand, if we have:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function Component() {
  const [foo, setFoo] = useState('a');
  const [bar, setBar] = useState('b');

  const handleClick = () => {
    setFoo('aa');
    setBar('bb');
  }

  return (
    <>
      <button onClick={handleClick}>
        click me
      </button>
      <p>{foo} {bar}</p>
   </>
  );
}

Then they’ll be batched.

If they’re batched, then the updates will show up immediately.

Conditional Rendering in styled-components

To render something conditionally with a component created with styled-components, we can pass in a function into the string with the props as the parameter.

For instance, we can write:

const Button = styled.button`
  width: 100%;
  outline: 0;
  border: 0;
  height: 100%;
  justify-content: center;
  align-items: center;
  line-height: 0.2;

  ${({ active }) => active && `
    background: green;
  `}
`;

We have a bunch of static styles.

In the end, we have a function that takes the active prop.

Then we return 'background: green' with active is true .

The styled.button template tag is a function that’ll convert the style string to a component with the styles.

And then can use it by writing:

<Button active={this.state.active}></Button>

We can also add conditional styles to an existing component by writing:

const StyledFoo = styled(Foo)`
  background: ${props => props.active ? 'blue' : 'green'}
`

We use the styled function which takes a component and returns a template tag.

Then we create a string with a function interpolated in it that takes the props and returns 'blue' or 'green' depending on if the active prop is true or not.

Only Allow Children of a Specific Type in a React Component

To allow children of a specific type in a React component, we can loop through each entry of children and then throw an error if we see something we don’t want.

To do that, we can create a custom validation function in the object that we set as the value of the propTypes property.

For instance, we can write:

class ItemGroup extends Component {
  render() {
    return (
      <div>{this.props.children}</div>
    )
  }
}

ItemGroup.propTypes = {
  children(props, propName, componentName) {
    const prop = props[propName]
    let error = null
    React.Children.forEach(prop, (child) => {
      if (child.type !== Item) {
        error = new Error(`${componentName} children should be Items`);
      }
    })
    return error;
  }
}

We created our own prop validation method to validate the children prop.

We get all the children with React.children and call forEach on it to loop through each item.

In the callback, we get the child element that we’re looping through and we can check the type of it with the type property.

If it doesn’t return something of type Item , we set the error and return it.

Prevent Multiple Button Presses with React

To prevent multiple button presses with React, we can use the disabled prop to disable the button after we clicked the button.

For instance, we can write:

class App extends React.Component {
  this.state = {
    disabled : false
  };

  handleClick = (event) => {
    if (this.state.disabled) {
      return;
    }
    this.setState({ disabled: true });
  }

  render() {
    return (
     <button onClick={this.handleClick} disabled={this.state.disabled}>
      {this.state.disabled ? 'Sending...' : 'Send'}
     <button>
    );
}

We have the handleClick method that checks the disabled state.

If it’s true , we do nothing.

Otherwise, we set thedisabled state to true and the button will be disabled because we passed that value to the disabled prop.

Conclusion

We can disable buttons on click with the disabled prop.

State updates are batched if they’re called synchronously in function components.

Styling can be done conditionally with styleled-components.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

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