ReactJS – Example ”; Previous Next In this chapter, let us create a sample expense manager application by applying the concepts that we have learned in this tutorial. Some of the concepts are listed below − React basics (component, jsx, props and state) Router using react-router Http client programming (Web API) Form programming using Formik Advanced state management using Redux Async / await programming Features Some of the features of our sample expense manager application are − Listing all the expenses from the server Add an expense item Delete an expense item Here, Expense manager API Install necessary modules State management List expenses Add expense Print Page Previous Next Advertisements ”;
Category: reactjs
ReactJS – Portals
ReactJS – Portals ”; Previous Next Portals provides a way for a component to render its children into a DOM node outside its own DOM hierarchy. Portal can be used in model dialog, popups, tooltip, etc., where the parent (the rendering component) and child DOM node (model dialogs) are preferred to be rendered in different DOM node. Let us learn how portal works and how to apply it in our application in this chapter. Concept and usage of portals Let us consider that we have two DOM node in the main document as shown below − <div id=”root”></div> <div id=”modalRoot”></div> Here, root DOM node will be attached with main react component. modalRoot will be used by the react application whenever it needs to show a modal dialog by attaching the modal dialog into the modelRoot DOM node instead of rendering the model dialog inside its own DOM element. This will help to separate the modal dialog from the actual application. The separation of modal dialog from its parent DOM element will preserve it from the styling of its parent DOM element. The styling can be applied separately as modal dialogs, tooltips, etc., differs from its parent with regard to styling. React provides a special method createPortal in ReactDOM package to create a portal. The signature of the method is as follows − ReactDOM.createPortal(child, container) Here, child is the model dialogs, tooltips, etc., rendered by the parent component. render() { return ReactDOM.createPortal( this.props.children, // modal dialog / tooltips domNode // dom outside the component ); } container is the DOM element outside the parent DOM node (domNode in above example) Applying portals Let us create a new react application to learn how to apply portals in this section. First of all, create a new react application and start it using below command. create-react-app myapp cd myapp npm start Next, open App.css (src/App.css) and remove all CSS classes and include CSS for modal dialogs. .modal { position: absolute; top: 0; bottom: 0; left: 0; right: 0; display: grid; justify-content: center; align-items: center; background-color: rgba(0,0,0,0.2); } .modalContent { padding: 20px; background-color: #fff; border-radius: 2px; display: inline-block; min-height: 300px; margin: 1rem; position: relative; min-width: 300px; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); justify-self: center; } Next, open index.html (public/index.html) and add a DOM node to support portals <!DOCTYPE html> <html lang=”en”> <head> <link rel=”icon” href=”%PUBLIC_URL%/favicon.ico” /> <link rel=”apple-touch-icon” href=”%PUBLIC_URL%/logo192.png” /> <link rel=”manifest” href=”%PUBLIC_URL%/manifest.json” /> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div style=”padding: 10px;”> <div id=”root”></div> </div> <div id=”modalRoot”></div> </body> </html> Next, create a simple component, SimplePortal (src/Components/SimplePortal.js) and render a modal dialog as shown below − import React from “react”; import PortalReactDOM from ”react-dom” const modalRoot = document.getElementById(”modalRoot”) class SimplePortal extends React.Component { constructor(props) { super(props); } render() { return PortalReactDOM.createPortal( <div className=”modal” onClick={this.props.onClose} > <div className=”modalContent”> {this.props.children} <hr /> <button onClick={this.props.onClose}>Close</button> </div> </div>, modalRoot, ) } } export default SimplePortal; Here, createPortal to create a new portal and renders a modal dialog. Content of the modal dialog are retrieved from children of the component through this.props.children close button actions are handled through props and will be handled by the parent component. Next, open App component (src/App.js), and use SimplePortal component as shown below − import ”./App.css” import React from ”react”; import SimplePortal from ”./Components/SimplePortal” class App extends React.Component { constructor(props) { super(props); this.state = { modal: false } } handleOpenModal = () => this.setState({ modal: true }) handleCloseModal = () => this.setState({ modal: false }) render() { return ( <div className=”container”> <div style={{ padding: “10px” }}> <div> <div><p>Main App</p></div> <div> <button onClick={this.handleOpenModal}> Show Modal </button> { this.state.modal ? ( <SimplePortal onClose={this.handleCloseModal}> Hi, I am the modal dialog created using portal. </SimplePortal> ) : null} </div> </div> </div> </div> ); } } export default App; Here, Imported SimplePortal component Added a button to open the modal dialog Created a handler to open the modal dialog Created a handler to close the modal dialog and passed it to SimplePortal component through onClose props. Finally, open the application in the browser and check the final result. Summary React portal provides an easy way to access and handle DOM outside the component. It enables the event bubbling across the different DOM nodes without any extra effort. Print Page Previous Next Advertisements ”;
ReactJS – Quick Guide
Reactjs – Quick Guide ”; Previous Next ReactJS – Introduction ReactJS is a free and open-source front-end JavaScript library which is used to develop various interactive user-interfaces. It is a simple, feature rich and component based UI library. When we say component based, we mean that React develops applications by creating various reusable and independent codes. This UI library is, thus, widely used in web development. ReactJS can be used to develop small applications as well as big, complex applications. ReactJS provides minimal and solid feature set to kick-start a web application. React community compliments React library by providing large set of ready-made components to develop web application in a record time. React community also provides advanced concept like state management, routing, etc., on top of the React library. React versions Reactjs library was founded by Jordan Walke, a software engineer at Facebook in 2011. Then the initial version, 0.3.0 of React is released on May, 2013 and the latest version, 17.0.1 is released on October, 2020. The major version introduces breaking changes and the minor version introduces new feature without breaking the existing functionality. Bug fixes are released as and when necessary. React follows the Semantic Versioning (semver) principle. What is the need for ReactJS? Even though there are various libraries that provide a medium to develop user-interfaces, ReactJS still stands tall in terms of popularity. Here”s why − Component Based − ReactJS makes use of multiple components to build an application. These components are independent and have their own logic which makes them reusable throughout the development process. This will drastically reduce the application”s development time. Better and Faster Performance − ReactJS uses Virtual DOM. Virtual DOM compares the previous states of components of an application with the current states and only updates the changes in Real DOM. Whereas, conventional web applications update all components again. This helps ReactJS in creating web applications faster. Extremely Flexible − React allows developers and teams to set their own conventions that they deem are best suited and implement it however they see fit, as there are no strict rules for code conventions in React. Creates dynamic applications easily − Dynamic web applications require less coding while offering more functionality. Thus, ReactJS can create them easily. Develops Mobile Applications as well − Not only web applications, React can also develop mobile applications using React Native. React Native is an open-source UI software framework that is derived from React itself. It uses React Framework to develop applications for Android, macOS, Web, Windows etc. Debugging is Easy − The data flow in React is unidirectional, i.e., while designing an app using React, child components are nested within parent components. As the data flows is in a single direction, it gets easier to debug errors and spot the bugs. Applications Few popular websites powered by React library are listed below − Facebook, popular social media application − React was originally developed at Facebook (or Meta), so its only natural that they use it to run their application. As for their mobile application, it uses React Native to display Android and iOS components, instead of DOM. Facebook”s codebase now includes over 20,000 components and uses the React version that is public. Instagram, popular photo sharing application − Instagram is also completely based on React, as it is powered by Meta as well. The main features to show its usage include Geo-locations, Hashtags, Google Maps APIs etc. Netflix, popular media streaming application − Netflix switched to React in 2015. The factors that mainly influenced this decision are the 1) startup speed to reduce the processing time to render the homepage and enabling dynamic elements in the UI, 2) modularity to allow various features that must coexist with the control experience and 3) runtime performance for efficient UI rendering. Code Academy, popular online training application − Code Academy uses React as the “script is battle-tested, easy to think about, makes SEO easy and is compatible with legacy code and flexible enough for the future”. Reddit, popular content sharing application − Reddit is also developed using React from the scratch. As you see, most popular application in every field is being developed by React Library. ReactJS – Installation This chapter explains the installation of React library and its related tools in your machine. Before moving to the installation, let us verify the prerequisite first. React provides CLI tools for the developer to fast forward the creation, development and deployment of the React based web application. React CLI tools depends on the Node.js and must be installed in your system. Hopefully, you have installed Node.js on your machine. We can check it using the below command − node –version You could see the version of Nodejs you might have installed. It is shown as below for me, v14.2.0 If Nodejs is not installed, you can download and install by visiting https://nodejs.org/en/download/. Toolchain To develop lightweight features such as form validation, model dialog, etc., React library can be directly included into the web application through content delivery network (CDN). It is similar to using jQuery library in a web application. For moderate to big application, it is advised to write the application as multiple files and then use bundler such as webpack, parcel, rollup, etc., to compile and bundle the application before deploying the code. React toolchain helps to create, build, run and deploy the React application. React toolchain basically provides a starter project template with all necessary code to bootstrap the application. Some of the popular toolchain to develop React applications are − Create React App − SPA oriented toolchain Next.js − server-side rendering oriented toolchain Gatsby − Static content oriented toolchain Tools required to develop a React application are
ReactJS – Integrating with Other Libraries ”; Previous Next Even though react provides all necessary feature to create a complete web application, integration with other libraries are a must due to legacy system coded in another library, migration from another framework, etc., React can co-exists with other libraries and provides necessary infrastructure to use along with other systems. Let us see how to use react component with other libraries like jQuery, backbone, etc., in this chapter. CreateRoot based integration React use createRoot() method from ReactDOMClient module to attach itself to the main HTML document. createRoot() does not disturbs the HTML document except attached element. This behaviour can be exploited by the developer to intermix multiple libraries in the same document. Let us see how to integrate jQuery and React component in a single document by attaching the react application in a separate element. First of all, create a new react application and start it using below command. create-react-app myapp cd myapp npm start Next, create a react component, Hello under component folder (src/components/Hello.js) import React from “react”; class Hello extends React.Component { constructor(props) { super(props) } render() { return ( <div>Hello, {this.props.name}</div> ); } } export default Hello; Next, open index.html (public/index.html) and add a new container (jquery-root) as shown below − <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”utf-8″ /> <link rel=”icon” href=”%PUBLIC_URL%/favicon.ico” /> <meta name=”viewport” content=”width=device-width, initial-scale=1″ /> <meta name=”theme-color” content=”#000000″ /> <meta name=”description” content=”Web site created using create-react-app” /> <link rel=”apple-touch-icon” href=”%PUBLIC_URL%/logo192.png” /> <link rel=”manifest” href=”%PUBLIC_URL%/manifest.json” /> <script src=”https://code.jquery.com/jquery-3.6.1.slim.min.js”></script> <title>React App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div style=”padding: 10px;”> <div id=”root”></div> <div id=”jquery-root”></div> </div> <script> $(document).ready(function() { $(“#jquery-root”).text(“Hello, from jQuery”) }) </script> </body> </html> Here, jQuery library in linked through CDN It is initialized as done traditionally through $(document).ready method And is used to append the message using jQuery selector (#jquery-root) and text method Next, open index.js (src/index.js) and attach our hello component into the root container as shown below − import React from ”react”; import ReactDOM from ”react-dom/client”; import ”./index.css”; import Hello from ”./Components/Hello”; import reportWebVitals from ”./reportWebVitals”; const root = ReactDOM.createRoot(document.getElementById(”root”)); root.render( <React.StrictMode> <Hello name=”from React” /> </React.StrictMode> ); reportWebVitals(); Here, React application is attached using createRoot() method. Rendered a Hello component into the root element in the HTML document. Finally, open the application in the browser and check the result. Both react and jQuery libraries emit the hello messages as shown below − Ref based integration In general, React does not know any DOM manipulation done by other libraries. So, to use React with other libraries, React should not do any DOM manipulation and should forward all changes to other libraries. As we know, React provides an escape hatch called Ref to manipulate DOM elements without affecting / affected by the state changes. Developer can exploit these feature to create a wrapper react component of some other library and use it in a react application. The standard steps to use other libraries in React component is as follow, Create a react component and renders an empty div render() { return <div /> } Attach a ref to the rendered div as shown below − render() { return <div ref={el => this.el = el} /> } Manipulate the dom element using attached ref in componentDidMount() life cycle event as shown below − componentDidMount() { this.$el = $(this.el); this.$el.somePlugin(); // create dom // call this.$el.pluginAPI() as necessary } Destroy the dom element using attached ref in componentWillUnmount() life cycle event as shown below − componentWillUnmount() { this.$el.somePlugin(”destroy”); // destroy dom // this.$el.destroyAPI() to remove the element from the dom } Let us apply these technics to integrate a jQuery plugin into the application in the next section. JQuery slick plugin integration Let us try to integrate slick jquery plugin (https://github.com/kenwheeler/slick) into a react component First of all, create a new react application and start it using below command. create-react-app myapp cd myapp npm start Next, install the slick jQuery plugin npm install jquery slick-carousel –save Next, copy the slick folder from slick plugin package (css and assets) into the app”s public folder. The content of the slider folder is as shown below − . ├── ajax-loader.gif ├── config.rb ├── fonts │ ├── slick.eot │ ├── slick.svg │ ├── slick.ttf │ └── slick.woff ├── slick-theme.css ├── slick-theme.less ├── slick-theme.scss ├── slick.css ├── slick.js ├── slick.less ├── slick.min.js └── slick.scss Next, create a simple component, ReactSlick (src/Components/ReactSlick.js) as shown below − import React from “react”; import $ from ”jquery”; import slick from ”slick-carousel”; class ReactSlick extends React.Component { componentDidMount() { this.$el = $(this.el); this.$el.slick(); } componentWillUnmount() { this.$el.slick(”destroy”); } render() { return ( <div> <div ref={el => this.el = el}> {this.props.children} </div> </div> ); } } export default ReactSlick; Here, Rendered a div with children from props Attached a ref to the div element Attached the plugin to the element using ref in componentDidMount() life cycle event Destroyed the plugin to the element using ref in componentWillUnmount life cycle event Next, open App component (src/App.js) and update the content with ReactSlick component as shown below − import ReactSlick from ”./Components/ReactSlick”; function App() { return ( <ReactSlick> <div className=”box”><h1>1</h1></div> <div className=”box”><h1>2</h1></div> <div className=”box”><h1>3</h1></div> <div className=”box”><h1>4</h1></div> </ReactSlick> ); } export default App; Here, Rendered the ReactSlick component Used four div with numbers (1,2,3 and 4) as sliders Next, open App.css (src/App.css) and remove all the CSS classes. Then, open index.html (public/index.html) and add a necessary styles as shown below − <!DOCTYPE html>
ReactJS – Controlled Component ”; Previous Next In controlled component, React provides a special attribute, value for all input elements and controls the input elements. The value attribute can be used to get and set the value of the input element. It has to be in sync with state of the component. In other words, a React component that render.s a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a “controlled component”. Controlled component has to follow a specific process to do form programming. Controlled Component With Single Input Let us check the step by step process to be followed for a single input element. Step 1 − Create a form element. <input type=”text” name=”username” /> Step 2 − Create a state for input element. this.state = { username: ”” } Step 3 − Add a value attribute and assign the value from state. <input type=”text” name=”username” value={this.state.username} /> Step 4 − Add a onChange attribute and assign a handler method. <input type=”text” name=”username” value={this.state.username} onChange={this.handleUsernameChange} /> Step 5 − Write the handler method and update the state whenever the event is fired. handleUsernameChange(e) { this.setState({ username = e.target.value }); } Step 6 − Bind the event handler in the constructor of the component. this.handleUsernameChange = this.handleUsernameChange.bind(this) Finally, get the input value using username from this.state during validation and submission. handleSubmit(e) { e.preventDefault(); alert(this.state.username); } Creating a Simple Form Let us create a simple form to add expense entry using controller component in this chapter. Step 1 − First, create a new react application, react-form-app using Create React App or Rollup bundler by following instruction in Creating a React application chapter. Step 2 − Open the application in your favorite editor. In the next step, create src folder under the root directory of the application. Further to the above process, create components folder under src folder. Step 3 − Create a file, ExpenseForm.css under src folder to style the component. input[type=text], input[type=number], input[type=date], select { width: 100%; padding: 12px 20px; margin: 8px 0; display: inline-block; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input[type=submit] { width: 100%; background-color: #4CAF50; color: white; padding: 14px 20px; margin: 8px 0; border: none; border-radius: 4px; cursor: pointer; } input[type=submit]:hover { background-color: #45a049; } input:focus { border: 1px solid #d9d5e0; } #expenseForm div { border-radius: 5px; background-color: #f2f2f2; padding: 20px; } Step 4 − Create a file, ExpenseForm.js under src/components folder and start editing. Step 5 − Import React library. import React from ”react”; Import ExpenseForm.css file. import ”./ExpenseForm.css” Step 6 − Create a class, ExpenseForm and call constructor with props. class ExpenseForm extends React.Component { constructor(props) { super(props); } } Initialize the state of the component. this.state = { item: {} } Create render() method and add a form with input fields to add expense items. render() { return ( <div id=”expenseForm”> <form> <label for=”name”>Title</label> <input type=”text” id=”name” name=”name” placeholder=”Enter expense title” /> <label for=”amount”>Amount</label> <input type=”number” id=”amount” name=”amount” placeholder=”Enter expense amount” /> <label for=”date”>Spend Date</label> <input type=”date” id=”date” name=”date” placeholder=”Enter date” /> <label for=”category”>Category</label> <select id=”category” name=”category” <option value=””>Select</option> <option value=”Food”>Food</option> <option value=”Entertainment”>Entertainment</option> <option value=”Academic”>Academic</option> </select> <input type=”submit” value=”Submit” /> </form> </div> ) } Create event handler for all the input fields to update the expense detail in the state. handleNameChange(e) { this.setState( (state, props) => { let item = state.item item.name = e.target.value; return { item: item } }); } handleAmountChange(e) { this.setState( (state, props) => { let item = state.item item.amount = e.target.value; return { item: item } }); } handleDateChange(e) { this.setState( (state, props) => { let item = state.item item.date = e.target.value; return { item: item } }); } handleCategoryChange(e) { this.setState( (state, props) => { let item = state.item item.category = e.target.value; return { item: item } }); } Bind the event handler in the constructor. this.handleNameChange = this.handleNameChange.bind(this); this.handleAmountChange = this.handleAmountChange.bind(this); this.handleDateChange = this.handleDateChange.bind(this); this.handleCategoryChange = this.handleCategoryChange.bind(this); Next, add an event handler for the submit action. onSubmit = (e) => { e.preventDefault(); alert(JSON.stringify(this.state.item)); } Attach the event handlers to the form. render() { return ( <div id=”expenseForm”> <form onSubmit={(e) => this.onSubmit(e)}> <label for=”name”>Title</label> <input type=”text” id=”name” name=”name” placeholder=”Enter expense title” value={this.state.item.name} onChange={this.handleNameChange} /> <label for=”amount”>Amount</label> <input type=”number” id=”amount” name=”amount” placeholder=”Enter expense amount” value={this.state.item.amount} onChange={this.handleAmountChange} /> <label for=”date”>Spend Date</label> <input type=”date” id=”date” name=”date” placeholder=”Enter date” value={this.state.item.date} onChange={this.handleDateChange} /> <label for=”category”>Category</label> <select id=”category” name=”category” value={this.state.item.category} onChange={this.handleCategoryChange} > <option value=””>Select</option> <option value=”Food”>Food</option> <option value=”Entertainment”>Entertainment</option> <option value=”Academic”>Academic</option> </select> <input type=”submit” value=”Submit” /> </form> </div> ) } Finally, export the component. export default ExpenseForm The complete code of the ExpenseForm component is as follows − import React from ”react”; import ”./ExpenseForm.css” class ExpenseForm extends React.Component { constructor(props) { super(props); this.state = { item: {} } this.handleNameChange = this.handleNameChange.bind(this); this.handleAmountChange = this.handleAmountChange.bind(this); this.handleDateChange = this.handleDateChange.bind(this); this.handleCategoryChange = this.handleCategoryChange.bind(this); } handleNameChange(e) { this.setState( (state, props) => { let item = state.item item.name = e.target.value; return { item: item } }); } handleAmountChange(e) { this.setState( (state, props) => { let item = state.item item.amount = e.target.value; return { item: item } }); } handleDateChange(e) { this.setState( (state, props) => { let item = state.item item.date = e.target.value; return { item: item } }); } handleCategoryChange(e) { this.setState( (state, props) => { let item = state.item item.category = e.target.value; return { item: item } }); } onSubmit = (e) => { e.preventDefault(); alert(JSON.stringify(this.state.item)); } render() { return ( <div id=”expenseForm”> <form onSubmit={(e) => this.onSubmit(e)}> <label for=”name”>Title</label> <input type=”text” id=”name”
ReactJS – Using useReducer
ReactJS – Using useReducer ”; Previous Next useReducer hook is an advanced version of useState hook. As we know, the purpose of the useState is to manage a state variable. useState returns a function, which accepts a value and updates the state variable with the given value. // counter = 0 const [counter, setCounter] = useState(0) // counter = 1 setCounter(1) // counter = 2 setCounter(2) The useReducer hook accepts a reducer function along with the initial value and returns a dispatcher function. Reducer function will accept the initial state and an action (specific scenario) and then provides logic to update the state based on the action. The dispatcher function accepts the action (and corresponding details) and call the reducer function with provided action. For example, useReducer can be used to update the counter state based on increment and decrement action. Increment action will increment the counter state by 1 and decrement action will decrement the counter by 1. Let us learn how to use useReducer hook in this chapter. Signature of the useReducer hook The signature of the useReducer hook is as follows − const [<state>, <dispatch function>] = useReducer(<reducer function>, <initial argument>, <init function>); Here, state represents the information to be maintained in the state reducer function is a javascript function used to update the state based on the action. Following is the syntax of the reducer function − (<state>, <action>) => <updated state> Where, state − Current state information action − Action to be carried out (should have payload to do the action) updated state − Updated state initial argument −represents the initial value of the state init function − represents initialization function, which can be used to set the initial value / reset the current value of the state. If initial value needs to be computed, then we can use the init function. Otherwise, the argument can be skipped. Applying reducer hook Let us create a react application to manage a collection of todo items. First of all, we will implement it using useState and then convert it to use useReducer. By implementing the application using both hook, we will understand the benefit of useReducer over useState. Also, we can able to choose the hook wisely depending on the situation. First of all, create a new react application and start it using below command. create-react-app myapp cd myapp npm start Next, create a react component, TodoList under component folder (src/components/TodoList.js). function TodoList() { return <div>Todo List</div> } export default TodoList Next, update the root component, App.js to use the newly created TodoList component. import logo from ”./logo.svg”; import ”./App.css”; import TodoList from ”./components/TodoList”; function App() { return ( <div style={{ padding: “5px”}}> <TodoList /> </div> ); } export default App; Next, create a variable, todoData to manage todo list and set it to the state using useState hook. const [todoData, setTodoData] = useState({ action: ””, items: [], newItem: null, id: 0 }) Here, action is used to represent the current action, add & delete to be applied on the current list of todo items (items). items is an array used to hold the current list of todo items. newItem is an object used to represent the current todo item. The object will have two field, id and todo. id is the id of the current item to be deleted during delete action. useState is used to get and set the todo list (todoData). Next, render the current list of todo item (todoData.items) along with a delete button and a input text field to enter new todo item. <div> <p>List of Todo list</p> <ul> {todoData.items && todoData.items.map((item) => <li key={item.id}>{item.todo} <span><button onClick={(e) => handleDeleteButton(item.id, e)}>Delete</button></span></li> )} <li><input type=”text” name=”todo” onChange={handleInput} /> <button onClick={handleAddButton}>Add</button></li> </ul> </div> Here, Rendered the current list of todo items from the state variable, todoData. Rendered a input field for the user to enter new todo item and attached onChange event handler, handleInput. The event handler will update newItem in the todo state (todoData) with the data entered by user in the input field. Rendered a button for the user to add the newly entered todo item to the current todo list and attached onClick event handler, handleAddButton. The event handler will add the current / new todo item to the todo state. Rendered a button for every item in the todo list and attached onClick event handler, handleDeleteButton. The event handler will delete the corresponding todo item from the todo state. Next, implement handleInput event handler as shown below − const handleInput = (e) => { var id = 0 if(todoData.newItem == null) { for(let i = 0; i < todoData.items.length; i++) { if(id < todoData.items[i].id) { id = todoData.items[i].id } } id += 1 } else { id = todoData.newItem.id } let data = { actions: ””, items: todoData.items, newItem: { id: id, todo: e.target.value }, id: 0 } setTodoData(data) } Here we have, Updated the newItem.todo with user entered data (e.target.value) Created and set the id for the new item. Next, implement handleDeleteButton event handler as shown below − const handleDeleteButton = (deleteId, e) => { let data = { action: ”delete”, items: todoData.items, newItem: todoData.newItem, id: deleteId } setTodoData(data) } Here, the handler set the id (deleteid) of the todo item to be deleted and delete action in the todo state Next, implement handleAddButton event handler as shown below − const handleAddButton = () => { let data = { action: ”add”, items: todoData.items, newItem: todoData.newItem, id: 0 } setTodoData(data) } Here, the handler set the new item
ReactJS – Accessibility
ReactJS – Accessibility ”; Previous Next Accessibility (a11y) is designing the web application in such a way that the application will be accessible by everyone and support assistive technology to read the content of the application for the end user. React supports all the aspects of accessibility in a web application. Let us see how react supports accessibility in this chapter. ARIA (aria-*) attributes WAI-ARIA (Web Accessibility Initiative – Accessible Rich Internet Applications) is a standard specifying ways to build fully accessible JavaScript widgets. It provides a large set of HTML attributes (aria-*) to support accessibility. React supports all those attributes in its components. In general, React restricts the HTML attributes to be in the form of camelCase, but for accessibility attributes, it should be in the form of kebab-case or lisp-case or simply as it is in the HTML document. For example, the below code shows how to use the HTML accessibility attributes. <input type=”text” aria-label={labelText} aria-required=”true” name=”name” /> Here, aria-label is used to specify the label of the input element aria-required is used to specify that the input should be filled. Note that the attributes are use as it is (in kebab-case format). Sematic HTML A web document coded by applying the sematic HTML (article, section, navigation, etc.,) tags improves the accessibility of the document. In react, there are situation where we use blocks (div) just to satisfy the react framework. For example, react does not support multiple tags in its render code. To overcome the restriction, developer may use parent tag (div) to make the multiple tags as children. function ShowItems({ data }) { return ( <div> <dt>{data.title}</dt> <dd>{data.description}</dd> </div> ); } React provides Fragment component to work around the scenario. We can just replace Fragment instead of div as shown below − function ShowItems({ data }) { return ( <Fragment> <dt>{data.title}</dt> <dd>{data.description}</dd> </Fragment> ); } Forms Every input should be labeled and the label should be descriptive to understand the input element. React provides a special props htmlFor to specify the input element for the specific description. Developer can use it create accessible forms. <label htmlFor=”firstName”>Firstname:</label> <input id=”firstName” type=”text” name=”name”/> Keyboard support Keyboard support is a must for creating accessible web application. Some of the features expecting keyboard support are, Focus − React provides a concept called Ref to access the raw DOM element. When the application needs raw access to DOM element, Ref and Forwarding Ref can be used to manage the raw DOM element. Skip links − Skip navigation links are must feature to support accessibility. They allows the user to skip all the navigation in one go when accessing the application using only keyboard. It can be done using smart anchor tags, which are fully supported by react. <body> <a href=”#maincontent”>Skip to main content</a> … <main id=”maincontent”> … </main> Mouse and pointer functionality − To create a true accessible application, all the feature should be accessible through keyboard. Component with high level mouse and pointer based user interaction should be changed to accommodate keyboard only user interaction. React provides all event handling logic to modify the default mouse based UI to keyboard based UI. Aria components React community provides many components with full accessibility support. They can be used as it is without any modification. They automatically enables the application to be accessible. Some of the third party components with aria support are as follows − react-aria − react-aria provides large set of react component with full accessibility support react-modal − react-modal provides modal component with aria support. react-aria-modal − react-aria-modal is yet another modal component with aria support. react-select − react-select provides select component with aria support. react-dropdown-aria − react-dropdown-aria provides dropdown component with aria support. react-aria-menubutton − react-aria-menubutton provides menu button component with aria support. react-aria-tabpanel − react-aria-tabpanel provides tab panel component with aria support. Summary React provides many features to create fully accessible, aria supported web application. Creation of accessible application is always a challenge and react reduces the burden a bit in the form of ready-made component as well as core feature to write a accessible application from the scratch. Print Page Previous Next Advertisements ”;
ReactJS – DOM
ReactJS – DOM ”; Previous Next To run a react application, it needs to be attached itself to the main document of the web application. React provides a module to access and attach the application to the DOM of the document and the module is ReactDOM (react-dom). Let us learn how to create a simple react component and attach the component into the document using reactDOM module in this chapter. ReactDOM usage react-dom is the core package used to manipulate the DOM of the document. react-dom allows one or more react application to be attached to the document. The react-dom should be imported into the application as shown below − import * as ReactDOM from ”react-dom”; The react-dom provides two method to manipulate the DOM and they are as follows − createPortal() − Create a portal in the react application. A portal is a special react node, which enables the main react application to render it”s children into the DOM outside of it”s own hierarchy of the DOM component. return ReactDOM.createPortal( this.props.children, // child node domNode // DOM node outside the root element ); Let us learn the portals in more details in the upcoming chapters. flushSync() − Flushes the state changes immediately and updates the DOM. Generally, react creates a virtual dom and then updates the real DOM by analyzing the differences between virtual and real DOM. The update frequency is determined internally by react. flushSync() interrupts and update the changes immediately. The react-dom provides two submodules, one for server side application and another for client side application. The modules are as follows − react-dom/server react-dom/client ReactDOMServer Server module will be used to render a react component in the server and the module can be imported as shown below − import * as ReactDOMServer from ”react-dom/server”; Some of the methods provided by ReactDOMServer are as follows − renderToPipeableStream() − Render a react component to its initial HTML and returns a pipe stream. renderToReadableStream() − Render a react component to its initial HTML and returns a readable web stream through promise. renderToStaticNodeStream() − Render a react component to its initial HTML and returns a readable nodejs stream that outputs a HTML string. It skips extra markup such as data-reactroot and the output will be same as renderToStaticMarkup(). renderToString() − Render a react component to its initial HTML and returns a HTML string. renderToStaticMarkup() −Same as renderToString() except it skips extra markup such as data-reactroot. ReactDOMClient Client module will be extensively used in the front-end development and can be imported into the application as shown below − import * as ReactDOM from ”react-dom/client”; Some of the methods provided by ReactDOMClient are as follows − createRoot() − Create a root element to attach and render a react component later. It accepts a html element and returns a react node. The react node is called as root of the application. The returned react node will have two method, render to render a react component and unmount to unmount the react component. const root = createRoot(container); root.render(element); // where element = document.getElementById(”root-id”) root.umount(); hydrateRoot() − Same as createRoot() but it is used in combination with react-dom/server module to hydrate the react component rendered in the server. Applying ReactDOMClient First of all, create a new react application and start it using below command. create-react-app myapp cd myapp npm start Next, create a react component, Hello under component folder (src/components/Hello.js). import React from “react”; class Hello extends React.Component { constructor(props) { super(props) } render() { return ( <div>Hello, {this.props.name}</div> ); } } export default Hello; Next, open index.html (public/index.html) and add a new container (root2) as shown below − <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”utf-8″ /> <link rel=”icon” href=”%PUBLIC_URL%/favicon.ico” /> <meta name=”viewport” content=”width=device-width, initial-scale=1″ /> <meta name=”theme-color” content=”#000000″ /> <meta name=”description” content=”Web site created using create-react-app” /> <link rel=”apple-touch-icon” href=”%PUBLIC_URL%/logo192.png” /> <link rel=”manifest” href=”%PUBLIC_URL%/manifest.json” /> <title>React App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div style=”padding: 10px;”> <div id=”root”></div> <div id=”root2″></div> </div> </body> </html> Next, open index.js (src/index.js) and attach our hello component into the root and root2 container as shown below − import React from ”react”; import ReactDOM from ”react-dom/client”; import ”./index.css”; import Hello from ”./Components/Hello”; import reportWebVitals from ”./reportWebVitals”; const root = ReactDOM.createRoot(document.getElementById(”root”)); root.render( <React.StrictMode> <Hello name=”Main root container” /> </React.StrictMode> ); const root2 = ReactDOM.createRoot(document.getElementById(”root2”)); root2.render( <React.StrictMode> <Hello name=”Another root container” /> </React.StrictMode> ); reportWebVitals();` Finally, open the application in the browser and check the result. The react component will be attached to both the root element as shown below − Summary ReactDOM provides the ability to create the entry point for the react application by attaching the react component into the HTML document in both client and server environment. Print Page Previous Next Advertisements ”;
ReactJS – Formik
ReactJS – Formik ”; Previous Next Formik is third party React form library. It provides basic form programming and validation. It is based on controlled component and greatly reduces the time to do form programming. The nature of form programming needs the state to be maintained. Because, the input field information will get changed as the user interacts with the form. But as we learned earlier, React library does not store or maintain any state information by itself and component has to use state management API to manage state. Considering this, React provides two types of components to support form programming. Expense Form Using Formik In this chapter, let us recreate the expense form using Formik library. Step 1 − First, create a new react application, react-formik-app using Create React App or Rollup bundler by following instruction in Creating a React application chapter. Step 2 − Install the Formik library. cd /go/to/workspace npm install formik –save Step 3 − Open the application in your favorite editor. Create src folder under the root directory of the application. Create components folder under src folder. Step 4 − Create a file, ExpenseForm.css under src folder to style the component. input[type=text], input[type=number], input[type=date], select { width: 100%; padding: 12px 20px; margin: 8px 0; display: inline-block; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input[type=submit] { width: 100%; background-color: #4CAF50; color: white; padding: 14px 20px; margin: 8px 0; border: none; border-radius: 4px; cursor: pointer; } input[type=submit]:hover { background-color: #45a049; } input:focus { border: 1px solid #d9d5e0; } #expenseForm div { border-radius: 5px; background-color: #f2f2f2; padding: 20px; } #expenseForm span { color: red; } Step 5 − Create another file, ExpenseForm.js under src/components folder and start editing. Import React and Formik library. import React from ”react”; import { Formik } from ”formik”; Next, import ExpenseForm.css file. import ”./ExpenseForm.css” Next, create ExpenseForm class. class ExpenseForm extends React.Component { constructor(props) { super(props); } } Set initial values of the expense item in the constructor. this.initialValues = { name: ””, amount: ””, date: ””, category: ”” } Next, create a validation method. Formik will send the current values entered by the user. validate = (values) => { const errors = {}; if (!values.name) { errors.name = ”Required”; } if (!values.amount) { errors.amount = ”Required”; } if (!values.date) { errors.date = ”Required”; } if (!values.category) { errors.category = ”Required”; } return errors; } Create a method to submit the form. Formik will send the current values entered by the user. handleSubmit = (values, setSubmitting) => { setTimeout(() => { alert(JSON.stringify(values, null, 2)); setSubmitting(false); }, 400); } Create render() method. Use handleChange, handleBlur and handleSubmit method provided by Formik as input elements event handler. render() { return ( <div id=”expenseForm”> <Formik initialValues={this.initialValues} validate={values => this.validate(values)} onSubmit={(values, { setSubmitting }) => this.handleSubmit(values, setSubmitting)} >{ ({ values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting, /* and other goodies */ }) => ( <form onSubmit={handleSubmit}> <label for=”name”>Title <span>{errors.name && touched.name && errors.name}</span></label> <input type=”text” id=”name” name=”name” placeholder=”Enter expense title” onChange={handleChange} onBlur={handleBlur} value={values.name} /> <label for=”amount”>Amount <span>{errors.amount && touched.amount && errors.amount}</span></label> <input type=”number” id=”amount” name=”amount” placeholder=”Enter expense amount” onChange={handleChange} onBlur={handleBlur} value={values.amount} /> <label for=”date”>Spend Date <span>{errors.date && touched.date && errors.date}</span></label> <input type=”date” id=”date” name=”date” placeholder=”Enter date” onChange={handleChange} onBlur={handleBlur} value={values.date} /> <label for=”category”>Category <span>{errors.category && touched.category && errors.category}</span></label> <select id=”category” name=”category” onChange={handleChange} onBlur={handleBlur} value={values.category}> <option value=””>Select</option> <option value=”Food”>Food</option> <option value=”Entertainment”>Entertainment</option> <option value=”Academic”>Academic</option> </select> <input type=”submit” value=”Submit” disabled={isSubmitting} /> </form> ) } </Formik> </div> ) } Finally, export the component. export default ExpenseForm The complete code of the ExpenseForm component is given below. import React from ”react”; import ”./ExpenseForm.css” import { Formik } from ”formik”; class ExpenseFormik extends React.Component { constructor(props) { super(props); this.initialValues = { name: ””, amount: ””, date: ””, category: ”” } } validate = (values) => { const errors = {}; if (!values.name) { errors.name = ”Required”; } if (!values.amount) { errors.amount = ”Required”; } if (!values.date) { errors.date = ”Required”; } if (!values.category) { errors.category = ”Required”; } return errors; } handleSubmit = (values, setSubmitting) => { setTimeout(() => { alert(JSON.stringify(values, null, 2)); setSubmitting(false); }, 400); } render() { return ( <div id=”expenseForm”> <Formik initialValues={this.initialValues} validate={values => this.validate(values)} onSubmit={(values, { setSubmitting }) => this.handleSubmit(values, setSubmitting)} > { ({ values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting, /* and other goodies */ }) => ( <form onSubmit={handleSubmit}> <label for=”name”>Title <span>{errors.name && touched.name && errors.name}</span></label> <input type=”text” id=”name” name=”name” placeholder=”Enter expense title” onChange={handleChange} onBlur={handleBlur} value={values.name} /> <label for=”amount”>Amount <span>{errors.amount && touched.amount && errors.amount}</span></label> <input type=”number” id=”amount” name=”amount” placeholder=”Enter expense amount” onChange={handleChange} onBlur={handleBlur} value={values.amount} /> <label for=”date”>Spend Date <span>{errors.date && touched.date && errors.date}</span></label> <input type=”date” id=”date” name=”date” placeholder=”Enter date” onChange={handleChange} onBlur={handleBlur} value={values.date} /> <label for=”category”>Category <span>{errors.category && touched.category && errors.category}</span></label> <select id=”category” name=”category” onChange={handleChange} onBlur={handleBlur} value={values.category}> <option value=””>Select</option> <option value=”Food”>Food</option> <option value=”Entertainment”>Entertainment</option> <option value=”Academic”>Academic</option> </select> <input type=”submit” value=”Submit” disabled={isSubmitting} /> </form> ) } </Formik> </div> ) } } export default ExpenseForm; index.js Create a file, index.js under the src folder and use ExpenseForm component. import React from ”react”; import ReactDOM from ”react-dom”; import ExpenseForm from ”./components/ExpenseForm” ReactDOM.render( <React.StrictMode> <ExpenseForm /> </React.StrictMode>, document.getElementById(”root”) ); index.html Finally, create a public folder under the root folder and create index.html file. <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”utf-8″> <title>React App</title> </head> <body> <div id=”root”></div> <script type=”text/JavaScript” src=”./index.js”></script> </body> </html> Serve the application using npm command. npm start Open the browser and enter http://localhost:3000 in the address bar and press enter. Finally, enter a sample expense detail and click submit. The submitted data will be collected and showed in a popup message box. The interactive version of the
ReactJS – Keys
ReactJS – Keys ”; Previous Next List and keys We learned how to use collections in React using for loop and map function in previous chapters. If we run the application, it output as expected. If we open the developer console in the browser, then it will show a warning as shown below − Warning: Each child in a list should have a unique “key” prop. Check the render method of `ExpenseListUsingForLoop`. See https://reactjs.org/link/warning-keys for more information. tr ExpenseListUsingForLoop@ div App So, what does it means and how it affects our React application. As we know, React tries to render only the updated values in DOM through various mechanism. When the React renders a collection, it tries to optimize the rendering by updating only the updated item in the list. But, there is no hint for the React to find which items are new, updated or removed. To get the information, React allows a key attributes for all components. The only requirement is that the value of the key should be unique among the current collection. Let us recreate one of our earlier application and apply the key attributes. create-react-app myapp cd myapp npm start Next, create a component, ExpenseListUsingForLoop under components folder (src/components/ExpenseListUsingForLoop.js). import React from ”react” class ExpenseListUsingForLoop extends React.Component { render() { return <table> <thead> <tr> <th>Item</th> <th>Amount</th> </tr> </thead> <tbody> </tbody> <tfoot> <tr> <th>Sum</th> <th></th> </tr> </tfoot> </table> } } export default ExpenseListUsingForLoop Here, we created a basic table structure with header and footer. Then, create a function to find the total expense amount. We will use it later in the render method. getTotalExpenses() { var items = this.props[”expenses”]; var total = 0; for(let i = 0; i < items.length; i++) { total += parseInt(items[i]); } return total; } Here, getTotalExpenses loop over the expense props and summarize the total expenses. Then, add expense items and total amount in the render method. render() { var items = this.props[”expenses”]; var expenses = [] expenses = items.map((item, idx) => <tr key={idx}><td>item {idx + 1}</td><td>{item}</td></tr>) var total = this.getTotalExpenses(); return <table> <thead> <tr> <th>Item</th> <th>Amount</th> </tr> </thead> <tbody> {expenses} </tbody> <tfoot> <tr> <th>Sum</th> <th>{total}</th> </tr> </tfoot> </table> } Here, Navigated each item in the expense array using map function, created table row (tr) for each entry using transform function and finally set the returned array in expenses variable. Set the key attributes for each row with the index value of the item. Used expenses array in the JSX expression to include the generated rows. Used getTotalExpenses method to find the total expense amount and add it into the render method. The complete source code of the ExpenseListUsingForLoop component is as follows − import React from ”react” class ExpenseListUsingForLoop extends React.Component { getTotalExpenses() { var items = this.props[”expenses”]; var total = 0; for(let i = 0; i < items.length; i++) { total += parseInt(items[i]); } return total; } render() { var items = this.props[”expenses”]; var expenses = [] expenses = items.map( (item, idx) => <tr key={idx}><td>item {idx + 1}</td><td>{item}</td></tr>) var total = this.getTotalExpenses(); return <table> <thead> <tr> <th>Item</th> <th>Amount</th> </tr> </thead> <tbody> {expenses} </tbody> <tfoot> <tr> <th>Sum</th> <th>{total}</th> </tr> </tfoot> </table> } } export default ExpenseListUsingForLoop Next, update the App component (App.js) with ExpenseListUsingForLoop component. import ExpenseListUsingForLoop from ”./components/ExpenseListUsingForLoop”; import ”./App.css”; function App() { var expenses = [100, 200, 300] return ( <div> <ExpenseListUsingForLoop expenses={expenses} /> </div> ); } export default App; Next, add include a basic styles in App.css. /* Center tables for demo */ table { margin: 0 auto; } div { padding: 5px; } /* Default Table Style */ table { color: #333; background: white; border: 1px solid grey; font-size: 12pt; border-collapse: collapse; } table thead th, table tfoot th { color: #777; background: rgba(0,0,0,.1); text-align: left; } table caption { padding:.5em; } table th, table td { padding: .5em; border: 1px solid lightgrey; } Next, check the application in the browser. It will show the expenses as shown below − Finally, open the developer console and find that the warning about key is not shown. Key and index We learned that the key should be unique to optimize the rendering of the component. We used index value and the error is gone. Is it still correct way to provide value for the list? The answer is Yes and No. Setting the index key will work in most situation but it will behave in unexpected ways if we use uncontrolled component in our application. Let us update our application and add two new features as specified below − Add an input element to each row adjacent to expense amount. Add a button to remove the first element in the list. First of all, add a constructor and set the initial state of the application. As we are going to remove certain item during runtime of our application, we should use state instead of props. constructor(props) { super(props) this.state = { expenses: this.props[”expenses”] } } Next, add a function to remove the first element of the list. remove() { var itemToRemove = this.state[”expenses”][0] this.setState((previousState) => ({ expenses: previousState[”expenses”].filter((item) => item != itemToRemove) })) } Next, bind the remove function in the constructor as shown below − constructor(props) { super(props) this.state = { expenses: this.props[”expenses”] } this.remove = this.remove.bind(this) } Next, add a button below the table and set remove function in its onClick action. render() { var items = this.state[”expenses”]; var expenses = [] expenses = items.map( (item, idx) => <tr key={idx}><td>item {idx + 1}</td><td>{item}</td></tr>) var total = this.getTotalExpenses(); return ( <div> <table> <thead> <tr> <th>Item</th> <th>Amount</th> </tr> </thead> <tbody> {expenses} </tbody> <tfoot> <tr> <th>Sum</th> <th>{total}</th> </tr> </tfoot> </table> <div> <button onClick={this.remove}>Remove first item</button> </div> </div>