Categories
React Tips

React Tips — Default Props and TypeScript, Copy Text to Clipboard

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.

Display Loading Screen While DOM is Rendering in Class Components

We can create a loading display in a React class component by putting our code in a few hooks.

For instance, we can write:

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      loading: true,
    }
  }

  componentDidMount() {
    this.timerHandle = setTimeout(() => this.setState({ loading: false }), 2000);
  }

  componentWillUnmount(){
    if (this.timerHandle) {
      clearTimeout(this.timerHandle);
    }
  }

  render(){
    return !loading && <div>hello world</div>;
  }
}

We have an App component, which has a timer created by calling setTimeout in the componentDidMount hook. It sets the loading state to false after 2 seconds. It’s initially set to true in the constructor. In our render method, we check the loading state and render something if it’s false .

Default Property Value in React Component Using TypeScript

We can set the default prop value in a React component by setting the defaultProps property in the component class.

For instance, we can write:

interface ItemProps {
  foo: string;
  bar: string;
}

export class Item extends React.Component<ItemProps, {}> {
  public static defaultProps = {
    foo: "default"
  };

  public render(): JSX.Element {
    return (
      <span>{this.props.foo.toUpperCase()}</span>
    );
  }
}

We created the ItemProps interfaces with a few properties. Then we pass that into the generic type parameter of React.Component to specify the prop names and types that are allowed. Inside the class, we set the static defaultProps property to set the default value of a prop.

With function components, we can write:

interface ItemProps {
  foo?: string;
  bar: number;
}

const ItemComponent: FunctionComponent<PageProps> = (props) => {
  return (
    <span>{props.foo}, {props.bar}</span>
  );
};

ItemComponent.defaultProps = {
  foo: "default"
};

We create an interface and then we pass it into the type parameter of the FunctionComponent generic type. Then we set the props’ default values with the defaultProps property.

useState Set Method Not Reflecting Change Immediately

useState ‘s state setting methods won’t reflect the changes immediately. They’ll be reflected in the next render cycle. To watch for the latest value of the state, we can use the useEffect hook.

For instance, we ecan write:

useEffect(() => { console.log(movies) }, [movies])

to watch for the latest value of the movies state.

React Component Names Must Begin with Capital Letters

We should create React components with names that begin with capital letters. This way, we can distinguish them between regular HTML elements and React components.

Get Derived State from Props

We can get derived state from props with memoize-one package. It’ll help us cache the values that are computed from props.

To install it, we run:

npm i memoize-one

Then we can use it by writing:

import memoize from "memoize-one";

const computeDerivedState = (props) => {
  //..
  return derivedState;
}

class App extends React.Component {
  constructor(){
    this.getDerivedData = memoize(computeDerivedState);
  }

  render() {
    const derivedData = this.getDerivedData(this.props.someValue);
    //...
  }
}

We have a computeDerivedState function which takes the props and compute something from them. Then we can use it in our render function to compute the value or get the memorized one if needed.

How to Copy Text to Clipboard

We can copy text to the clipboard by using the document.execCommand method.

For instance, we can write:

import React from 'react';

class Copy extends React.Component {

  constructor(props) {
    super(props);
    this.state = { copySuccess: '' }
  }

  copyToClipboard(e){
    this.textArea.select();
    document.execCommand('copy');
  };

  render() {
    return (
      <div>
        {
         document.queryCommandSupported('copy') &&
          <div>
            <button onClick={this.copyToClipboard}>Copy</button>
            {this.state.copySuccess}
          </div>
        }
        <form>
          <textarea
            ref={(textarea) => this.textArea = textarea}
            value='foo bar'
          />
        </form>
      </div>
    );
  }

}

We have a text area with some text we can copy. It’s assigned a ref so we can access its content later when we copy the text. We check if the copy command is supported by the document.queryCommandSupported method. We display the copy button if it’s supported. The button will call the copyToClipboard method if it’s clicked. In the method, we call the select method on the text area to select the text to copy. Then we run document.execCommand to run the copy command.

Conclusion

We can copy text to the clip with the copy command. Also, we can display things differently when our content is loading. Default prop values can be set with TypeScript and React. Thanks for reading my article, I hope you found it helpful!

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 *