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.