You might have a form created in your React App that user might try to close by closing the tab, reloading the page or close the browser directly. You might want to prompt the user in this case to alert them that there might be unsaved changes that might be lost.
The following example binds the “beforeunload” event to the App Component and the unbinds it on the componentwillunmount event. This could apply to form component and not the Parent App component.
You can even call an API to make the necessary changes required for your App at the back-end before the browser unloads the Page. But please be careful in case the user decides to cancel and stays on the page. I’ve tested the above code on Google Chrome and Edge Chromium.
I haven’t really found a way that let’s you customize the prompt message in the modern browsers. And there is no way to capture the Leave/Cancel (stay) button click events. Let me know if you find a way to capture these events. However, I believe the browser has given control to the user more than the Page in case of unload.
IE11 is still among the most popular browsers in the world. Though Microsoft is promoting Edge Browser on Chromium engine. Many organizations have still not moved on to new offerings or taking their own time. Meanwhile, if you need to make your React Application compatible with IE11, check the steps below:
Create the app, follow this post, if not already done.
Add import 'react-app-polyfill/ie11'; as the first line in index.js file.
For common standard functions like Array.find() that are not supported in IE 11 add import 'react-app-polyfill/stable'. This should be the 2nd line in index.js file.
In package.json copy the production browserlist to development so you can test in IE11 and all other browsers that will work in production. Just add "ie 11" at the end of both production and development, browserlist section into package.json
//browsers list in package.json file in reference to #4:
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all",
"IE 11"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version",
"IE 11"
]
}
If you are also using arrow functions so you’ll also need babel to update that for you. The babel-plugin-transform-arrow-functions is your best solution for this. Please check the documentation here.
you might still face some issues in your functionality like additional spaces added by Material UI date control which fails in IE11 but not other browsers. This might need to be taken care of individually on operations using that date value.
There is a simple way to write a function in Javascript to format the date as dd mmm yyyy. I’m using this method in my ReactJS code to simply format the date and set the state with the returned string wherever required.
formatDate(date) {
if (date !== undefined && date !== "") {
var myDate = new Date(date);
var month = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
][myDate.getMonth()];
var str = myDate.getDate() + " " + month + " " + myDate.getFullYear();
return str;
}
return "";
}
You can call this method from your JS code like this:
Install the latest Material UI core package from npm:
npm install @material-ui/core @latest
Import the following components required for the Dialog box:
import React from "react";
import { withStyles } from "@material-ui/core/styles";
import Checkbox from "@material-ui/core/Checkbox";
import Dialog from "@material-ui/core/Dialog";
import DialogContent from "@material-ui/core/DialogContent";
import DialogActions from '@material-ui/core/DialogActions';
import { DialogContentText } from "@material-ui/core";
import MuiDialogTitle from "@material-ui/core/DialogTitle";
import CloseIcon from '@material-ui/icons/Close';
import Typography from '@material-ui/core/Typography';
import Button from "@material-ui/core/Button";
import IconButton from '@material-ui/core/IconButton';
Add the following styles for the Dialog content and buttons:
Setting the isDialogOpen to true on clicking checkbox will open the Dialog box with OK and Cancel Action buttons. Each Action button has it’s own handler.
Here I’m using axios to call the API via Post request. Passing the credentials in the call with create. The token part is optional in the Headers, you can add/remove headers based on your requirement.
From the WebAPI end, I’m using .Net core. You can receive the file in the Action method as below:
[HttpPost]
[Route("upload")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult UploadForm([FromQuery] string username)
{
var request = HttpContext.Request;
if (request.Form.Files.Count > 0)
{
filename = request.Form.Files[0].FileName;
extension = filename.Substring(filename.LastIndexOf(".")).ToLower();
if (!string.IsNullOrEmpty(extension) && extension.Equals(".docx"))
{
using (var memoryStream = new MemoryStream())
{
request.Form.Files[0].CopyTo(memoryStream);
// Upload the file if less than 2 MB
if (memoryStream.Length < 2097152)
{
string check = Service.CheckifValid(username);
if (check.Equals("ok"))
{
//Process the stream and pass the data to the back-end in the Service Layer.
result = Service.UploadStream(memoryStream, filename, extension, username);
}
else
{
return Ok(check);
}
}
else
{
return BadRequest("File size too large");
}
}
}
else
{
return BadRequest("File format not recognised.");
}
}
//Other ToDos...
}
Create a basic ReactJS App using the create-react-app Post here.
Our final aim is to generate a Radar Chart using the npmjs package react-svg-radar-chart. Also, the dot markings on the chart should be able to show the current index and key, values on the chart on Hover as shown below.
Create the Project or directory on your file system. My local folder is called formik-sample. You can also create using the create-react-app Post here for a sample ReactJS App.
Create a repository on Github. I’ve named it sample-form-reactjs.
Click on Clone or Download. Copy the SSH link.
Open the local folder in VS Code as created in Step 1.
In the Terminal Window in VS Code, type the following commands:
After this is done, just follow the same steps for git stage/commit/push etc.
For # 3:
However, if Step 5. gives error like below:
Check your network firewall settings if you’re doing it from Office. Try it out from your home and it should work.
Also, you can clone git@github which is SSH version but for that you have generate ssh keys and have to set it in local environment and if you don’t want to set up that then just use https version in the above clone command.
If you face branch related errors, since you might have already created a repo on Github, you can create a new branch as below:
I’ve created a basic React App as described in my previous post. This is just a demo on how you can use fetch API to load data in the componentDidMount() lifecycle method with/without async/await. I’ve not used any error handling yet.
The basic structure of the React App contains index.js and index.html files. The code is added to my Github profile.
Replace the code of the index.js file as below:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
Create App.js file under the src directory and add the below code:
import React, { Component } from "react";
import MyComp from "./MyComp";
export default class App extends Component {
render() {
return (
<div className="App">
<MyComp />
</div>
);
}
}
It’s time to create MyComp which is the sample component that will call the placeholder JSON API to show the list of users using Fetch GET request.
The async function which in this case is the componentDidMount contains the await expression that pauses the execution of the async function. It waits until the passed Promise is resolved. It then resumes the async function’s execution and evaluates as the resolved value.
Run the App again to see the results which are the same in this case.
You can also include headers and credentials in the Fetch call as shown below:
We can declare special methods on the component class to run some code when a component mounts and unmounts also called lifecycle methods.
A ReactJS component goes through the following phases: initialization, mounting, updating and unmounting.
constructor() – Not a lifecycle method exactly.
State should usually be assigned in the constructor as it is used to set the initial state of our component. You can directly set the state property inside the constructor as setState method is not available before the component is mounted.
componentWillMount()
This was deprecated in post React 17.0. If you still continue using this, you should use UNSAFE_componentWillMount().
render()
Rendering happens when the component mounts or updates. It has to be pure i.e. it cannot modify the state using setState. It should only handle the rendering of your component to the UI.
componentDidMount()
You can make calls to a remote endpoint like an Web Service or API to load data and is the best place to do so. Using setSate here will cause state updates and cause another rendering that happens before the browser updates the UI. States should usually be assigned in the constructor though as mentioned above.
componentDidUpdate()
This method is called in response to props or state changes. setState should only be used with caution as may lead to inifinite loop. You can wrap it in a condition as shown below:
componentDidUpdate(prevProps) {
//Compare the props
if (this.props.title !== prevProps.title) {
//do something -- here we have compared the current props with the previous props before doing something.
}
}
componentWillUnmount()
This is the end of the lifecycle before the component is unmounted and destroyed. This can be used for any cleanups like clearing storage caches.
Create a basic ReactJS App, to follow through the example. You can check this post to get started.
In the example below to check out how these Component methods are called to depict the life cycle, the output for all these methods are logged to the Console.
The constructor initializes the state of the Component. The render method is called after every ComponentWill methods. Once the Component is rendered to the DOM, the ComponentDid method is called.
The componentDidMount() method runs after the component output has been rendered to the DOM.