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.
Detecting User Leaving Page with React Router
React Router has the Prompt
component to let us block navigation with a message.
For instance, we can write:
import { Prompt } from 'react-router'
const App = () => (
<React.Fragment>
<Prompt
when={shouldBlockNavigation}
message='Are you sure you want to leave?'
/>
{/* more components */}
</React.Fragment>
)
We have the Prompt
which takes a when
prompt with a boolean expression that indicates when we want to block navigation.
message
is the message to display when the user tries to leave.
It’ll block anything but not page refresh or closing.
To block refresh or closing, we’ve to set the onbeforeunload
property to different values depending on whether navigation is blocked or not.
For instance, we can write:
componentDidUpdate = () => {
if (shouldBlockNavigation) {
window.onbeforeunload = () => true
} else {
window.onbeforeunload = undefined
}
}
If navigation should be blocked when refreshing or closing the browser tab, then we set it window.onbeforeunload
to a function that returns true
.
Otherwise, we set it to undefined
.
Avoid Extra Wrapping <div> in React
We can use a fragment to avoid wrapper an extra div outside our components.
For instance, we can write:
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}
or:
render() {
return (
<>
<ChildA />
<ChildB />
<ChildC />
</>
);
}
Deal with a Fetch Error in react-redux
We can use redux-thunk to create an async action that calls dispatch
to dispatch synchronous actions on error.
For instance, we can write:
export function getData() {
return dispatch => {
dispatch({type: FETCH });
httpClient.get('/data')
.then(res => {
dispatch({ type: FETCH_SUCCESS, data: res.body });
})
.catch(error => {
dispatch({type: FAILED });
dispatch({type: ADD_ERROR, error });
});
};
}
We have a thunk that gets data and calls dispatch
to dispatch various actions.
In our errors
reducer, we can write:
function errors(state = [], action) {
switch (action.type) {
case ADD_ERROR:
return [...state, action.error];
case REMOVE_ERROR:
return state.filter((error, i) => i !== action.index);
default:
return state;
}
}
We have the errors
reducer that has the ADD_ERROR
case to add errors and another case to remove the given error.
Then we can map the errors
state to props by writing:
export default connect(
state => ({
errors: state.errors,
})
)(App);
where App
is a React component.
Tell the Version of React Running at Runtime in the Browser
We can get the React.version
property to get the version of React running in the browser.
There’s also the:
npm view react version
npm view react-native version
to get the React version.
require(‘React’).version
also works.
Remove the /#/ in the Browser with React Router
To remove the hash sign from the URL with React Roytee, we can use the BrowserRouter
as the route root tag,.
For instance, we can write:
import BrowserRouter from 'react-router/BrowserRouter'
ReactDOM.render ((
<BrowserRouter>
{//...}
<BrowserRouter>
), document.body);
We also need to rewrite the URLs to redirect to index.html
so we won’t get errors when loading or refreshing the page:
# Setting up apache options
AddDefaultCharset utf-8
Options +FollowSymlinks -MultiViews -Indexes
RewriteEngine on
# Defining the rewrite rules
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.html
This config is for Apache servers.
Render React Components Separated by a Comma by Using map and reduce
We can render React components with map
and join
by mapping the items to components.
Then we can use reduce
to put commas between the components.
For instance, we can write:
class CommaList extends React.Component {
render() {
<div>
{this.props.data
.map(t => <span>{t}</span>)
.reduce((combined, curr) => [combined, ', ', curr])}
</div>
}
}
We get the data
prop, which is an array.
Then we call map
to map them to components.
And then we call reduce
to add commas between the components that are already joined with commas, which is stored in combined
and the new component stored in curr
.
Conclusion
We can detect situations when the users leave the page in React Router.
We can combine components in an array separated by commas with reduce
.
Also, we can dispatch actions when errors occur with Redux.