Categories
React Tips

React Tips — Mock React-Redux, Internationalization, and Connect Redux with React

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.

How to Unit Test React-Redux Connected Components

We can test a React-Redux connected component by mocking the connect function and Provider component with our own code.

For instance, we can write:

jest.mock('react-redux', () => {
  return {
    connect: (mapStateToProps, mapDispatchToProps) => (Component) => ({
      mapStateToProps,
      mapDispatchToProps,
      Component
    }),
    Provider: ({ children }) => children
  }
})

We create a mock version of React Redyx by creating a mock module with the connect function.

It takes a mapStateToProps and mapDispatchToProps methods like the real thing.

And it returns a function that takes a React component and returns an object with all the parameters in it.

To mock the Provider we just return the children from the prop.

This can be used inline within a file.

To put the mock in a separate file, we can write:

module.exports = {
  connect: (mapStateToProps, mapDispatchToProps) => (Component) => ({
    mapStateToProps,
    mapDispatchToProps,
    Component,
  }),
  Provider: ({children}) => children
};

in __mocks__/react-redux.js .

The __mocks__ folder should be in the root folder.

Unless we call jest.unmock(‘react-redux’)) the mock will be used.

PropTypes in Stateless Functional Component

We can set prop types in stateless function components.

For instance, we can write:

import React from 'react';
import PropTypes from 'prop-types';

function List(props) {
  const todos = props.todos.map((todo, index) => (<p key={index}>{todo}</p>));
  return (<div>{todos}</div>);
}

List.propTypes = {
  todos: PropTypes.array.isRequired,
};

We assign the propTypes property with an object with the prop types.

And then we use the PropTypes object to specify the type.

How to Maintain State After a Page Refresh in React

To maintain state after a page refresh in React, we can store the state we want to keep in local storage.

For instance, we can write:

constructor() {
  const selectedOption = localStorage.getItem('selectedOption');
  this.state = {
    selectedOption
  };
}

setSelectedOption(option) {
  localStorage.setItem('selectedOption', option);
  this.setState({ selectedOption: option });
}

We have the constructor that gets the saved state from local storage with getItem .

Then in another method, we set the option in the local storage and the state.

Use Redux’s Store with React

To access a Redux store with a React component, we can use the connect function.

For instance, we can write:

import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'

const mapStateToProps = (state, ownProps) => {
  return {
    active: ownProps.name === state.name
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    onClick: () => {
      dispatch(setName(ownProps.name))
    }
  }
}

const NameLink = connect(
  mapStateToProps,
  mapDispatchToProps
)(Link)

export default NameLink

With our mapStateToProps function, we return the active Redux state as a prop for the Link component.

Also, we have the mapDispatchToProps function to let us create a function that calls dispatch dispatch an action to our Redux store.

Then we can pass them all to the connect function, which returns a higher-order component.

Then we can pass in our Link component to return a new component to add the state and dispatch functions as props.

How to use FormattedMessage in input placeholder with React-Intl

To pass in a placeholder that’s translated with the react-intl, we can call the formatNwessage method with an object to interpolate the placeholders.

For instance, we can write:

import React from 'react';
import { injectIntl, intlShape } from 'react-intl';

const Input = ({ intl }) => {
  const placeholder = intl.formatMessage({ id: 'messageId' });
  return(
     <input placeholder={placeholder} />
  );
}

Input.propTypes = {
  intl: intlShape.isRequired
}

export default injectIntl(Input);

We use the injectIntl higher-order component to inject the intl prop to our component.

It has the formatMessage method that we can interpolate our placeholders with.

It returns a string so that we can use it in in our placeholder prop.

With function components, we can use the useIntl hook to do the same thing.

For instance, we can write:

import React from 'react';
import { useIntl } from 'react-intl';

const Input = () => {
  const intl = useIntl();
  const placeholder = intl.formatMessage({ id: 'messageId' });
  return(
     <input placeholder={placeholder} />
  );
};

export default Input;

We use the useIntl hook to get the intl object.

Then we can call formatMessage on it to interpolate our string.

Conclusion

We can use the react-intl for internationalization.

Also, the react-redux module can be mocked in our tests.

Props types can be set in function components.

We can save our state to local storage to make it persist during refresh.

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 *