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”
Category: reactjs
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 – Properties (props)
ReactJS – Properties (props) ”; Previous Next React enables developers to create dynamic and advanced component using properties. Every component can have attributes similar to HTML attributes and each attribute”s value can be accessed inside the component using properties (props). For example, Hello component with a name attribute can be accessed inside the component through this.props.name variable. <Hello name=”React” /> // value of name will be “Hello* const name = this.props.name React properties supports attribute”s value of different types. They are as follows, String Number Datetime Array List Objects Using Props When we need immutable data in our component, we can just add props to reactDOM.render() function in main.js and use it inside our component. App.jsx import React from ”react”; class App extends React.Component { render() { return ( <div> <h1>{this.props.headerProp}</h1> <h2>{this.props.contentProp}</h2> </div> ); } } export default App; main.js import React from ”react”; import ReactDOM from ”react-dom”; import App from ”./App.jsx”; ReactDOM.render(<App headerProp = “Header from props…” contentProp = “Content from props…”/>, document.getElementById(”app”)); export default App; This will produce the following result. Default Props You can also set default property values directly on the component constructor instead of adding it to the reactDom.render() element. App.jsx import React from ”react”; class App extends React.Component { render() { return ( <div> <h1>{this.props.headerProp}</h1> <h2>{this.props.contentProp}</h2> </div> ); } } App.defaultProps = { headerProp: “Header from props…”, contentProp:”Content from props…” } export default App; main.js import React from ”react”; import ReactDOM from ”react-dom”; import App from ”./App.jsx”; ReactDOM.render(<App/>, document.getElementById(”app”)); Output is the same as before. State vs Props The following example shows how to combine state and props in your app. We are setting the state in our parent component and passing it down the component tree using props. Inside the render function, we are setting headerProp and contentProp used in child components. App.jsx import React from ”react”; class App extends React.Component { constructor(props) { super(props); this.state = { header: “Header from props…”, content: “Content from props…” } } render() { return ( <div> <Header headerProp = {this.state.header}/> <Content contentProp = {this.state.content}/> </div> ); } } class Header extends React.Component { render() { return ( <div> <h1>{this.props.headerProp}</h1> </div> ); } } class Content extends React.Component { render() { return ( <div> <h2>{this.props.contentProp}</h2> </div> ); } } export default App; main.js import React from ”react”; import ReactDOM from ”react-dom”; import App from ”./App.jsx”; ReactDOM.render(<App/>, document.getElementById(”app”)); The result will again be the same as in the previous two examples, the only thing that is different is the source of our data, which is now originally coming from the state. When we want to update it, we just need to update the state, and all child components will be updated. More on this in the Events chapter. Let us learn the following concepts one by one in this chapter. Create a component using Properties Nested Components Use Component Component Collection Print Page Previous Next Advertisements ”;
ReactJS – Using useState
ReactJS – Using useState ”; Previous Next useState is a basic React hook, which allows a function component to maintain its own state and re-render itself based on the state changes. The signature of the useState is as follows − const [ <state>, <setState> ] = useState( <initialValue> ) where, initialValue − Initial value of the state. state can be specified in any type (number, string, array and object). state − Variable to represent the value of the state. setState − Function variable to represent the function to update the state returned by the useState. The signature of the setState function is as follows − setState( <valueToBeUpdated> ) Where, valueToBeUpdated is the value to be updated for the state. The sample usage to set and update the user”s name is as follows − // initialize the state const [name, setName] = useState(”John”) // update the state setName(”Peter) Features Notable features of useState are as follows − Function Parameter − It Accepts a function (returns initial state) instead of initial value and execute the function only once during initial rendering of the component. This will help to improve the performance, if the computation of initial value is expensive. const [val, setVal] = useState(() => { var initialValue = null // expensive calculation of initial value return initialValue }) Verifies the previous values − It checks the current and previous value of the state and only if they are different, React renders its children and fires the effects. This will improve performance of the rendering. // … setName(”John”) // update the state and rerender the component // … // … setName(”John”) // does not fire the rendering of the children because the value of the state have not changed. // … Batches multiple state updates − Multiple state updates are batched and processed by React internally. If multiple state update has to be done immediately, then the special function flushSync provided by React can be used, which will immediately flush all the state changes. flushSync(() => setName(”Peter”)) Applying state hook Let us create a login form component and maintain the values of the form using useState hook. First of all, create and start a React application using below commands, create-react-app myapp cd myapp npm start Next, create a react component, LoginForm under component folder (src/components/LoginForm.js) import { useState } from ”react”; export default function LoginForm() { // render code } Next, create two state variable, username and password using useState hook as shown below − import { useState } from ”react”; export default function LoginForm() { const [username, setUsername] = useState(””) const [password, setPassword] = useState(””) // render code } Next, create a function to validate the login data as shown below − import { useState } from ”react”; export default function LoginForm() { const [username, setUsername] = useState(””) const [password, setPassword] = useState(””) let isEmpty = (val) => { if(val == null || val == ””) { return true; } else { return false; } } let validate = (e) => { e.preventDefault() if(!isEmpty(username) && !isEmpty(password)) { alert(JSON.stringify({ username: username, password: password })) } else { alert(“Please enter username / password”) } } // render code } Here, isEmpty is a function to check whether the data is available or empty. Next, render a login form with two input fields and use state variables (username and password), state updated methods (setUsername and setPassword) and validate method to process the form. import { useState } from ”react”; export default function LoginForm() { return ( <div style={{ textAlign: “center”, padding: “5px” }}> <form name=”loginForm”> <label for=”username”>Username: </label> <input id=”username” name=”username” type=”text” value={username} onChange={(e) => setUsername(e.target.value)} /> <br /> <label for=”password”>Password: </label> <input id=”password” name=”password” type=”password” value={password} onChange={(e) => setPassword(e.target.value)} /> <br /> <button type=”submit” onClick={(e) => validate(e)}>Submit</button> </form> </div> ) } Here, onChange uses the state setting function returned by hooks. onClick uses the validate function to validate and show the user entered data. The complete code of the LoginForm component is as follows − import { useState } from ”react”; export default function LoginForm() { const [username, setUsername] = useState(””) const [password, setPassword] = useState(””) let isEmpty = (val) => { if(val == null || val == ””) { return true; } else { return false; } } let validate = (e) => { e.preventDefault() if(!isEmpty(username) && !isEmpty(password)) { alert(JSON.stringify({ username: username, password: password })) } else { alert(“Please enter username / password”) } } return ( <div style={{ textAlign: “center”, padding: “5px” }}> <form name=”loginForm”> <label for=”username”>Username: </label> <input id=”username” name=”username” type=”text” value={username} onChange={(e) => setUsername(e.target.value)} /> <br /> <label for=”password”>Password: </label> <input id=”password” name=”password” type=”password” value={password} onChange={(e) => setPassword(e.target.value)} /> <br /> <button type=”submit” onClick={(e) => validate(e)}>Submit</button> </form> </div> ) } Next, update the root application component, App.js as below, import ”./App.css”; import HelloWorld from ”./components/HelloWorld”; import LoginForm from ”./components/LoginForm”; function App() { return ( <LoginForm /> ); } export default App; Next, open the browser and check the application. Application will gather the user entered data using state variable and validate it using validate function. if user entered proper data, it will show the data as shown below − Otherwise, it will throw the error as shown below − Object as state In class based state management, setState method supports partial update of the state object. For example, let us consider login form data is maintained in state as an object. { username: ”John”, password: ”secret” } Updating the username using setState will only update the username in the state object and preserve the password field. this.setState({ username: ”Peter”
ReactJS – Using useEffect
ReactJS – Using useEffect ”; Previous Next React provides useEffect to do side-effects in a component. Some of the side effects are as follows − Fetching data from external source & updating the rendered content. Updating DOM elements after rendering. Subscriptions Using Timers Logging In class based components, these side effects are done using life cycle components. So, useEffect hook is an effect replacement for below mentioned life cycle events. componentDidMount − Fires after the rendering is done for the first time. componentDidUpdate − Fires after the rendering is updated due to prop or state changes. componentWillUnmount − Fires after the rendered content is unmounted during destruction of component. Let us learn how to use effect hook in this chapter. Signature of useEffect The signature of useEffect is as follows − useEffect( <update function>, <dependency> ) where, the signature of the update function is as follows − { // code return <clean up function> } Here, Update function − Update function is the function to be executed after each render phase. This corresponds to componentDidMount and componentDidUpdate events Dependency − Dependency is an array with all the variables on which the function is dependent. Specifying the dependency is very important to optimize the effect hook. In general, update function is called after each render. Sometimes it is not necessary to render update function on each render. Let us consider that we are fetching data from external source and updating it after the render phase as shown below − const [data, setDate] = useState({}) const [toggle, setToggle] = useState(false) const [id, setID] = useState(0) useEffect( () => { fetch(”/data/url/”, {id: id}).then( fetchedData => setData(fetchedData) ) }) // code Component will rerender whenever data and toggle variable are updated. But as you see, we don”t need that the defined effect to be run during each update of toggle state. To fix the issue, we can pass an empty dependency as shown below − const [data, setDate] = useState({}) const [toggle, setToggle] = useState(false) const [id, setID] = useState(0) useEffect( () => { fetch(”/data/url/”, { id: id }).then( fetchedData => setData(fetchedData) ) }, []) The above code will run the effect only once after the first render. Even though it will fix the issus, the effects has to be run on every change of id. To make it happen, we can include id as dependency for the effects as shown below − const [data, setDate] = useState({}) const [toggle, setToggle] = useState(false) const [id, setID] = useState(0) useEffect( () => { fetch(”/data/url/”, { id: id }).then( fetchedData => setData(fetchedData) ) }, [id]) This will ensure that the effects will rerun only after the modification of id Cleanup function − Cleanup function is used to cleanup work during the usage of subscription function and timer function as shown below − const [time, setTime] = useState(new Date()) useEffect(() => { let interval = setInterval(() => { setTime(new Date()) }, 1000) return () => clearInterval(interval) }, [time]) Let us create a complete application to understand the cleanup function in later section. Features of effect hook Some of the notable features of effect hook are as follows − React allows multiple effect hook to be used in a function component. This will help us to write a function for each side effects and set it up as separate effect. Each hook will be run in the order in which it is declared. Developer should make sure that the order of effects are declared correctly. Dependency feature can be used to improve the performance and correct working of the side effects. Cleanup function prevents memory leaks and unnecessary firing of events. Fetching data using effect Let us create an application that will fetch data from external source and render it using useEffect hook 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, create a react component, NameList under component folder (src/components/NameList.js) function NameList() { return <div>names</div> } export default NameList Here, the purpose of the NameList component is to showcase the popular list of common names Next, update the root component, App.js to use the newly created NameList component. import NameList from “./components/NameList”; function App() { return ( <div style={{ padding: “5px”}}> <NameList /> </div> ); } export default App; Next, create a json file, names.json (public/json/names.json) and store popular names in json format as shown below. [ { “id”: 1, “name”: “Liam” }, { “id”: 2, “name”: “Olivia” }, { “id”: 3, “name”: “Noah” }, { “id”: 4, “name”: “Emma” }, { “id”: 5, “name”: “Oliver” }, { “id”: 6, “name”: “Charlotte” }, { “id”: 7, “name”: “Elijah” }, { “id”: 8, “name”: “Amelia” }, { “id”: 9, “name”: “James” }, { “id”: 10, “name”: “Ava” }, { “id”: 11, “name”: “William” }, { “id”: 12, “name”: “Sophia” }, { “id”: 13, “name”: “Benjamin” }, { “id”: 14, “name”: “Isabella” }, { “id”: 15, “name”: “Lucas” }, { “id”: 16, “name”: “Mia” }, { “id”: 17, “name”: “Henry” }, { “id”: 18, “name”: “Evelyn” }, { “id”: 19, “name”: “Theodore” }, { “id”: 20, “name”: “Harper” } ] Next, create a new state variable, data to store popular names in NameList component as shown below − const [data, setData] = useState([]) Next, create a new state variable, isLoading to store loading status as shown below − const [isLoading, setLoading] = useState([]) Next, use fetch method to get popular names from json file and set it into data state variable inside useEffect hook useEffect(() => { setTimeout(()
ReactJS – Table
ReactJS – Table ”; Previous Next React provides table component through third party UI component library. React community provides a large collection of UI / UX components and it is tough to choose the right library for our requirement. Bootstrap UI library is one of the popular choice for the developer and it is extensively used. React Bootstrap (https://react-bootstrap.github.io/) has ported almost all the bootstrap UI components to the React library and it has best support for Table component as well. Let us learn how to use Table component from react-bootstrap library in this chapter. Table component Table component allows the developer to create simple table with bootstrap UI design in a web application. Table component accepts table tags as shown below − thead tbody tfoot Table component accepts a small set of props to customize the table component and they are follows − bordered (boolean) − Adds border to all sides of the table and cell. borderless (boolean) −Removes border to all sides of the table and cell. hover (boolean) − Enables a hover state for each row in the table (tbody). responsive (boolean | string) − Enables vertical scrolling for small devices. sm | md | lg | xl option enables the responsive for relevant devices. For example, sm will be enabled only when the device resolution is very small. size (string) − Enables compact rendering of the table. Possible options are sm, md, etc., striped (boolean | string) − Enables the zebra stripping to all table rows. columns option adds zebra stripping to columns as well. variant (dark) Enables dark variant when dark value is used. bsPrefix (string) − Prefix used to customize the underlying CSS classes. Applying Table 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 bootstrap and react-bootstrap library using below command, npm install –save bootstrap react-bootstrap Next, open App.css (src/App.css) and remove all CSS classes. // remove all css classes Next, create a simple table component, SimpleTable (src/Components/SimpleTable.js) and render a table as shown below − import { Table } from ”react-bootstrap”; function SimpleTable() { return ( <Table striped bordered hover> <thead> <tr> <th>#</th> <th>Name</th> <th>Age</th> <th>Email</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>John</td> <td>25</td> <td>[email protected]</td> </tr> <tr> <td>1</td> <td>Peter</td> <td>15</td> <td>[email protected]</td> </tr> <tr> <td>1</td> <td>Olivia</td> <td>23</td> <td>[email protected]</td> </tr> </tbody> </Table> ); } export default SimpleTable; Here we have, Used striped props to create zebra tables. Used bordered props to enable border around the table and cells. Used hover props to enable hover state. Next, open App component (src/App.js), import the bootstrap css and update the content with bootstrap button as shown below − import ”./App.css” import “bootstrap/dist/css/bootstrap.min.css”; import SimpleTable from ”./Components/SimpleTable” function App() { return ( <div className=”container”> <div style={{ padding: “10px” }}> <div> <SimpleTable /> </div> </div> </div> ); } export default App; Here we have, Imported the bootstrap classes using import statement. Rendered our new SimpleTable component. Included the App.css style. Finally, open the application in the browser and check the final result. Table component will be rendered as shown below − Add dark variant and column strip Let us apply dark variant and column strip option in our table component and see how it updates the table design. First of all, open our carousel application and update the SimpleCarousel component as shown below − import { Table } from ”react-bootstrap”; function SimpleTable() { return ( <Table bordered hover striped=”columns” variant=”dark”> // … Here we have, Used striped props with columns to enable column based zebra stripping as well. Used variant props with dark option to enable dark variant of the table design. Next, open the application in the browser and check the final result. Table component will be rendered with column strip and dark variant as shown below − Summary Bootstrap table component provides all necessary options to design a table in a simple, intuitive and flexible manner. Print Page Previous Next Advertisements ”;
ReactJS – Context
ReactJS – Context ”; Previous Next Context is one of the important concept in React. It provides the ability to pass a information from the parent component to all its children to any nested level without passing the information through props in each level. Context will make the code more readable and simple to understand. Context can be used to store information which does not change or have minimal change. Some of the use cases of context are as follows − Application configuration Current authenticated user information Current user setting Language setting Theme / Design configuration by application / users Let us learn how to create context and its usage in this chapter. How context works? Let us learn the basic concept of context and how it works. Context has four parts, Creating a new context Setting context provider in the root component Setting context consumer in the component where we need the context information Accessing context information and using it in render method Let us create an application to better understand context and its usage. Let us create a global context for maintaining theme information in the application root component and use it in our child component. First of all, create and start an application using below command, create-react-app myapp cd myapp npm start Next, create a component, HelloWorld under components folder (src/components/HelloWorld.js) import React from “react”; import ThemeContext from “../ThemeContext”; class HelloWorld extends React.Component { render() { return <div>Hello World</div> } } export default HelloWorld Next, create with a new context (src/ThemeContext.js) for maintaining theme information. import React from ”react” const ThemeContext = React.createContext({ color: ”black”, backgroundColor: ”white” }) export default ThemeContext Here, A new context is created using React.createContext. Context is modeled as an object having style information. Set initial value for color and background of the text. Next, update the root component, App.js by including HelloWorld component and the theme provider with initial value for the theme context. import ”./App.css”; import HelloWorld from ”./components/HelloWorld”; import ThemeContext from ”./ThemeContext” function App() { return ( <ThemeContext.Provider value={{ color: ”white”, backgroundColor: ”green” }}> <HelloWorld /> </ThemeContext.Provider> ); } export default App; Here, the ThemeContext.Provider is used, which is a non-visual component to set the value of the theme context to be used in all its children component. Next, include a context consumer in HelloWorld component and style the hello world message using theme information in HelloWorld component. import React from “react”; import ThemeContext from “../ThemeContext”; class HelloWorld extends React.Component { render() { return ( <ThemeContext.Consumer> {({color, backgroundColor} ) => (<div style={{ color: color, backgroundColor: backgroundColor }}> Hello World </div>) } </ThemeContext.Consumer> ) } } export default HelloWorld Here, Used ThemeContext.Consumer, which is a non-visual component providing access to the current theme context details Used a function expression to get the current context information inside ThemeContext.Consumer Used object deconstruction syntax to get the theme information and set the value in color and backgroundColor variable. Used the theme information to style the component using style props. Finally, open the browser and check the output of the application Summary Context reduces the complexity of maintaining global data in a react application. It provides a clean concept of provider and consumer and simplifies the implementation of context. Print Page Previous Next Advertisements ”;