Categories
React Tips

React Tips — this, Merging States, and Mock Functions in Tests

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.

Merging States with setState Instead of Overwriting

We can merge states with setState instead of overwriting if we pass in a callback to the method instead of an object.

For instance, instead of writing:

this.setState({ x: 1 });

We write:

this.setState((prevState, props) => ({
  point: {
    ...prevState.point,
    y: 1
  },
));

We pass in a callback that gets the previous state as the first parameter.

Then we merge in the previous state’s value into the returned object.

And we add y after it.

How to Change a Jest Mock Function Return Value in Each Test

We can change the mock function implementation by creating the mock function with jest.fn() .

Then we can the mockImplementation method by passing in a callback that returns the value we want.

Or we can pass the return value as the argument.

For instance, we can write:

import { foo, bar } from './module';

jest.mock('./module', () => ({
  foo: jest.fn(),
  bar: jest.fn()
}));

We mock the module’s methods with jest.fn() .

Then we call mockImplementation on it by writing:

foo.mockImplementation(() => true)

or:

foo.mockImplementation(true)

in our tests.

In a different test, we can write:

foo.mockImplementation(() => false)

or:

foo.mockImplementation(false)

There’s also the mockReturnValueOnce method that we can use.

For instance, we can write:

import { foo, bar } from './module';

jest.mock('./module', () => ({
  foo: jest.fn(),
  bar: jest.fn()
}));

describe('test suite', () => {
  it('some test', () => {
    foo.mockReturnValueOnce(true);
    bar.mockReturnValueOnce(false);
  });
});

Replace img src on Error in React

We can add an error handler to our img element to load another image on error.

For instance, we can write:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Image extends Component {
  constructor(props) {
    super(props);

    this.state = {
      src: props.src
    };
  }

  onError = () => {
    this.setState({
      src: this.props.fallbackSrc,
    });
  }

  render() {
    const { src } = this.state;

    return (
      <img
        src={src}
        onError={this.onError}
        {...props}
      />
    );
  }
}

Image.propTypes = {
  src: PropTypes.string,
  fallbackSrc: PropTypes.string,
};

We replace the src state with the fallbackSrc in our error handler.

This way, when the image with the given src string can’t load, then we set it to the fallbackSrc value as the value of img’s src attribute’s value.

Creating an “If” Component with React

We can use boolean expressions to create a component that displays something conditionally.

For instance, we can write:

<div>
  {(cond
    ? <div>It's true</div>
    : <div>It's false</div>
  )}
</div>

If cond is true , then <div>It’s true</div> is shown.

Otherwise, <div>It’s false</div> is shown.

We can also have null or false as an empty component that doesn’t render anything.

For instance, we can write:

<div>
  {showChild ? <Child /> : false}
</div>

If showChild is true , we show the Child component.

Otherwise, we show nothing.

We can also use an if statement bu writing:

renderPerson() {
  const personName = '';
  if (personName) {
    return <div>{personName}</div>;
  }
}

We show personName if it exists.

Then in render , we write:

render() {
  return (
    <div>
      {this.renderPerson()}
    </div>
  );
}

We render the personName if it exists.

Also, we can write:

{cond && (<div>It's true</div>)}

Passing Object as Props to JSX

To pass an object as props with JSX, we can use the spread operator.

For instance, we can write:

<Child  {...commonProps} />

where commonProps is an object.

The all the keys are passed in as props.

And all the values are passed in as the props’ values.

Fix React this.state is Undefined

If we’re using this.state in our class methods, then we should call bind to set the class as the value of this inside the method.

For instance, we can write:

<Form onClick={this.onClick.bind(this)}/>

Then the this value inside the this.onClick method would be set to the class since this is the class.

Putting this.onClick.bind(this) into the prop will create a new function on every render, so we should put it in the constructor to avoid that:

constructor(props) {
  super(props);
  this.state = {
    users: null
  }
  this.onClick = this.onClick.bind(this);
}

Conclusion

We can mock Jest methods’ return value with a few methods.

Also, we can merge states instead of overwriting them.

We can conditionally render items.

And we’ve to call bind to set this to the class.

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 *