Unit 3
Unit 3
JS
2. Controlled component
• In HTML, form elements typically maintain their own state and
update it according to the user input.
• In the controlled component, the input form element is handled
by the component rather than the DOM.
• Here, the mutable state is kept in the state property and will be
updated only with setState() method.
• Controlled components have functions that govern the data
passing into them on every onChange event, rather than grabbing
the data only once, e.g., when you click a submit button. This data
is then saved to state and updated with setState() method. This
makes component have better control over the form elements
and data.
• A controlled component takes its current value through props and
notifies the changes through callbacks like an onChange event.
Unit-3: Forms and Hooks in React.JS
• A parent component "controls" these changes by handling the
callback and managing its own state and then passing the new
values as props to the controlled component. It is also called as a
"dumb component."
import React, { Component } from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('You have submitted the input successfully: ' + this.state.val
ue);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h1>Controlled Form Example</h1>
<label>
Name:
<input type="text" value={this.state.value} onChange={th
is.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
export default App;
Unit-3: Forms and Hooks in React.JS
SN Controlled Uncontrolled
1. It does not maintain its internal state. It maintains its internal states.
2. Here, data is controlled by the parent Here, data is controlled by the DOM itself.
component.
3. It accepts its current value as a prop. It uses a ref for their current values.
5. It has better control over the form elements It has limited control over the form elements
and data. and data.
function FavoriteColor() {
const [color, setColor] = useState("");
}
Read State
function FavoriteColor() {
Unit-3: Forms and Hooks in React.JS
const [color, setColor] = useState("red");
Update State
import { useState } from "react";
import ReactDOM from "react-dom/client";
function FavoriteColor() {
const [color, setColor] = useState("red");
return (
<>
<h1>My favorite color is {color}!</h1>
<button
type="button"
onClick={() => setColor("blue")}
>Blue</button>
</>
)
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<FavoriteColor />);
function Car() {
const [brand, setBrand] = useState("Ford");
const [model, setModel] = useState("Mustang");
const [year, setYear] = useState("1964");
const [color, setColor] = useState("red");
return (
<>
<h1>My {brand}</h1>
<p>
It is a {color} {model} from {year}.
</p>
</>
)
}
function Car() {
const [car, setCar] = useState({
brand: "Ford",
model: "Mustang",
year: "1964",
color: "red"
});
return (
<>
<h1>My {car.brand}</h1>
<p>
It is a {car.color} {car.model} from {car.year}.
</p>
</>
)
}
useEffect
• The useEffect Hook allows you to perform side effects in your
components.
• Some examples of side effects are: fetching data, directly updating the
DOM, and timers.
• useEffect accepts two arguments. The second argument is optional.
useEffect(<function>, <dependency>)
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
});
Unit-3: Forms and Hooks in React.JS
return <h1>I've rendered {count} times!</h1>;
}
• useEffect runs on every render. That means that when the count changes,
a render happens, which then triggers another effect.
• We should always include the second parameter which accepts an array.
We can optionally pass dependencies to useEffect in this array.
No dependency passed
useEffect(() => {
//Runs on every render
});
An empty array
useEffect(() => {
//Runs only on the first render
}, []);
function Counter() {
const [count, setCount] = useState(0);
const [calculation, setCalculation] = useState(0);
useEffect(() => {
setCalculation(() => count * 2);
}, [count]); // <- add the count variable here
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
<p>Calculation: {calculation}</p>
</>
);
}
Unit-3: Forms and Hooks in React.JS
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Counter />);
Effect Cleanup
• Some effects require cleanup to reduce memory leaks.
• Timeouts, subscriptions, event listeners, and other effects that are no
longer needed should be disposed.
• A return function at the end of the useEffect Hook.
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
let timer = setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
useContext
• To set the global data and this data can now be accessed in any of the
children’s components without the need to pass it through every parent
Component.
• Syntax
const authContext = useContext(initialValue);
The use Context accepts the value provided
by React.createContext and then re-render the component whenever its
value changes but you can still optimize its performance by
using memoization.
AuthContext.js
import React from 'react';
function App() {
const [inputValue, setInputValue] = useState("");
const count = useRef(0);
useEffect(() => {
count.current = count.current + 1;
});
return (
<>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<h1>Render Count: {count.current}</h1>
</>
);
}
const root =
ReactDOM.createRoot(document.getElementById('root'));
Unit-3: Forms and Hooks in React.JS
root.render(<App />);
function App() {
const inputElement = useRef();
return (
<>
<input type="text" ref={inputElement} />
<button onClick={focusInput}>Focus Input</button>
</>
);
}
useReducer
useReducer(<reducer>, <initialState>)
• The reducer function contains your custom state logic and the initial State
can be a simple value but generally will contain an object.
Unit-3: Forms and Hooks in React.JS
• The useReducer Hook returns the current state and a dispatch method.
const initialTodos = [
{
id: 1,
title: "Todo 1",
complete: false,
},
{
id: 2,
title: "Todo 2",
complete: false,
},
];
function Todos() {
const [todos, dispatch] = useReducer(reducer, initialTodos);
return (
<>
{todos.map((todo) => (
<div key={todo.id}>
<label>
<input
type="checkbox"
checked={todo.complete}
onChange={() => handleComplete(todo)}
/>
{todo.title}
Unit-3: Forms and Hooks in React.JS
</label>
</div>
))}
</>
);
}
useCallback
• The React useCallback Hook returns a memoized callback function.
• This allows us to isolate resource intensive functions so that they will not
automatically run on every render.
• The useCallback Hook only runs when one of its dependencies update.
• This can improve performance.
• One reason to use useCallback is to prevent a component from re-
rendering unless its props have changed.
index.js
return (
<>
<Todos todos={todos} addTodo={addTodo} />
<hr />
Unit-3: Forms and Hooks in React.JS
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
</>
);
};
Todos.js
import { memo } from "react";
useMemo
• The React useMemo Hook returns a memorized value.
• The useMemo Hook only runs when one of its dependencies update.
• This can improve performance.
• The useMemo Hook can be used to keep expensive, resource intensive
functions from needlessly running.
return (
<div>
<div>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Add Todo</button>
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
<h2>Expensive Calculation</h2>
{calculation}
</div>
</div>
);
};
• React.Js provides lots of built-in hooks that you can use in your React
apps.
• You can make your own custom hooks and use it in your apps resulting
in better readability and a reduced amount of code.
• Custom hooks are normal JavaScript functions whose names start with
“use” and they may call other hooks(built-in or custom).
Custom hooks give us following benefits:
• When a piece of code (logic) is reused in many places (it’s easy to see
when you copy a whole piece of code without editing anything, except
for the parameter passed. Split like how you separate a function).
• When the logic is too long and complicated, you want to write it in
another file, so that your component is shorter and easier to read
because you don’t need to care about the logic of that hook anymore.