1.) Always use functional version to update state to update state proper
Example :-
function App(){
const[number,setNumber] = useState(0);
const increase =() => {
setNumber(number + 1)
}
const increaseAsync =() => {
setTimeout(() => {
setNumber((currentNumber)=> currentNumber + 1);//like this
setNumber(number +1)///not like this
},2000);
}
return (
‹div>
‹button onClick={increase)>Increase</button>
‹button onClick={increaseAsync)>IncreaeAsync</button>
<h1>{number}</h1>
</div>
);
}
export default App;
2.) Make proper State Initialization
Error :- Generate error like Cannot read properties of undefined ( reading 'name')
function App (){
//const [user, setuser] = useState()
const [user, setuser] = useState({
Username:"",
email:"",
images:[]
})
// user: {
//name:"john",
//email:"john@gmail.com",
//images: ["profile.png", "cover -png" ]
//}
return (
‹div>
<span>Username is: {user.name)</span>//not to use like this
<span>Username is: {user?.name)</span>//use like this
<span>Username is: {user && user.name)</span>//or use like this
<span>Profile Picture is: {user.images[1])</span>//this gives error
//or you can inititalize state properly like below
//const [user, setuser] = useState({})//here our state is object
//
</div>
);
}
export default App;
3.) Update specific object property
function App() {
const [input, setInput] = useState("");
const [user, setUser] = useState ({
name: "john",
email: "john@gmail. com",
images: ["profile.png", "cover.png"],
}) ;
const changeUser = () => {
setUser ((prev) => ({ ...prev, name: input }));
};
console. log (user);
return (
‹div>
<h2>User: </h2>
‹input onChange={(e) => setInput (e. target.value)} placeholder="enter a new name.../>
‹button onClick={changeUser}>Change username</button>
‹span>Username is: {user.name)}</span>
‹/div>
}
4.) Change all inputs with a single onChange
import { useState ) from "react";
import "./style-css";
function App() {
const [user, setuser] = useState({
name: "",
surname:"",
username:"",
email: "",
password:"",
country: "",
city: "",
address: "",
})
const handleChange =(e)=>
setUser (prev=>({...prev,[e.target.name]: e. target.value}))
}
console.log(user);
return (
‹div>
‹form>
<input type="text" name="name" onChange={handlChange} />
<input type="text" name="surname" onChange={handlChange}/>
<input type="text" name="username" onChange={handlChange}/>
<input type="text" name="email" onChange={handlChange}/>
‹input type="text" name="password" onChange={handlChange}/>
<input type="text" name="country" onChange={handlChange}/>
<input type="text" name="city" onChange={handlChange}/>
<input type="text" name="address" onChange={handlChange}/>
‹button>Submit</button>
</form>
</div>
);
}
export default App;
5.) UseState vs useReducer when to use ?
---> when you have complex object then use useReducer hook
import { useState } from "react";
import "./style.css";
function App() {
const [product, setProduct] = useState({
title: ""
desc: "",
price: 0,
category: "",
tags: [],
images: {
sm:"",
md:"",
lg:"",
},
quantity: 0,
});
return (
<div>
<form>
<input type="text" placeholder="Title" />
<input type="text" placeholder="Desc" />
<input type="number" placeholder="Price" />
<p> Category: </p>
<select name="cars" id="cars">
<option value="sneakers">Sneakers</option>
<option value="tshirts">T-shirts</option>
<option value="jeans">Jeans</option>
</ select>
<p>Tags:</p>
<textarea placeholder="Seperate tags with comma" />
<div className="quantity">
<button>-</button>
<span>Quantity ({product. quantity}) </span>
<button>+</button>
</div>
</form>
</div>
);
};
export default App;
6.) Derive States Incorrectly
import "-/style.css";
function App() {
const [products, setProducts] = useState([
{id: 1, title: "black sneakers", quantity: 1},
{id: 2, title: "red t-shirt", quantity: 1},
{id: 3, title: "blue jeans", quantity: 1},
]);
const [selectedProduct, setSelectedProduct] = useState();
const increment = (id) => {
setProducts ((prev) => {
return prev.map((product)=> {
if (product. id === id) {
return {... product,quantity: product.quantity + 1 };
} else return product;
});
});
};
const handleChoose = (id)=> {
const product = products.find((p)=> p.id === id);
setSelectedProduct (product);
};
return (
<div>
<h4> All Products</h4>
{products.map((product)=> (
<div key={product.id}>
<span>{product. title}
<button onClick={() => handleChoose(product.id)}>Choose</button>
</span>
<div className="quantity">
<button>-</button>
<span>{product.quantity}</span>
<button onClick={() => increment(product.id)}>+</button>
</div>
</div>
))}
<h4>Selected Product</h4>
<span>{selectedProduct.title}</span>
<span>{selectedProduct.quantity}</span>
</div>
);
};
export default App;
use like below
import { useState } from 'react';
import "./style.css";
function App() {
const [products, setProducts] = useState([
{ id: 1, title: "black sneakers", quantity: 1},
{ id: 2, title: "red t-shirt", quantity: 1 },
{ id: 3, title: "blue jeans", quantity: 1 },
]);
const [selectedId, setSelectedId] = useState(null);
const selectedProduct = products.find((p)=> p.id === selectedId);
const increment = (id) => {
setProducts ((prev) => {
return prev.map((product)=> {
if (product. id === id) {
return {... product, quantity: product.quantity + 1 };
} else return product;
});
});
};
const handleChoose = (id)=> {
setSelectedId(id);
};
return (
<div>
<h4> All Products</h4>
{products.map((product)=> (
<div key={product.id}>
<span>{product. title}
<button onClick={() => handleChoose(product.id)}>Choose</button>
</span>
<div className="quantity">
<button>-</button>
<span>{product.quantity}</span>
<button onClick={() => increment(product.id)}>+</button>
</div>
</div>
))}
<h4>Selected Product</h4>
<span>{selectedProduct?.title}</span>
<span>{selectedProduct?.quantity}</span>
</div>
);
};
export default App;
7.) Don't use useState if not needed in form
import { useRef } from "react";
function App() {
const emailRef = useRef()
const passwordRef = useRef()
function onSubmit(e) {
e.preventDefault()
console.log({ email:emailRef.current.value,
password : passwordRef.current.value
})
}
return (
<form onSubmit={onSubmit}>
<label htmlFor="email">Email</label>
<input ref={emailRef} type="email" id="email" />
<label htmlFor="password">Password</label>
<input ref={passwordRef} type="password" id="password" />
<button type="submit">Submit</button>
</form>
)
}
export default App
8.) State update are not immediate
"use client";
import { useState } from "react";
export default function Counter () {
const [count, setCount] = useState(0) ;
const handleClick = () => {
//Use prev value to update state value instead use count variable
//setCount (count + 1)
//setCount (count + 1);
//setCount (count + 1);
//setCount (count + 1);
setCount ((prev) => prev + 1);
setCount ((prev) => prev + 1);
setCount ((prev) = prev + 1);
setCount ((prev) => prev + 1);
};
return (
<>
<button onClick={handleClick} className="bg-blue-500 px-4 py-2 text-white rounded mb">Click me<button>
<p>Count is : {count}</p>
</>
)
9.) Conditional Rendering
use only one return statement and use below hooks (like useState and use Effect)
export default function ProductCard(f id }) {
if (!id) {
return "No id provided";
}
return ‹section>{/* Product card... */}</section>;
}
use like below
"use client";
import { useEffect, useState } from "react";
export default function ProductCard({ id }) {
const [something, setSomething] = useState("blabla");
useEffect(() => (J, [something]);
return (
<section>
{ !id ? "No id provided" :{ /* Product card... * / }}
</section>
) ;
}
10.) Updating object State
"use client";
import { useState } from "react";
export default function User() {
const [user, setUser] = useState({name:"",city:"",age: 50 });
const handleChange = (e) => {
//setUser((user.name = e.target.value));//not use like this because we have state is object not single value
setUser({
...user,//copy all old value object
name: e.target.value // overwrite new value to object for name property
});
//OR
//some user use like below as well
setUser(prev => ({
...prev,
name: e.target.value
}));
//OR
//some user use like below as well
setUser(prev => {
return{
...prev,
name: e.target.value
};
});
};
return (
<form>
<input type="text" onChange={handleChange} placeholder="Your name" /›
</form>
);
}
11.) Use object state instead of multiple smaller once
note :- Makje sure your object key is same as form input name property
Example here for For FirstName --> object key is firstName and input namr is also firstName.
"use client";
import { useState } from "react";
export default function Form() {
const [form, setForm] = useState({
firstName: ""
lastName: ""
email: ""
password: ""
address: ""
zipCode: ""
}) ;
//Don't use like below function
/*const handleChange = e => {
setForm({
...form,
firstName : e.target.value
})
};*/
//Use Like below instead use above
const handleChange = (e) => {
setForm({
...form,
[e.target.name] : e.target.value
})
};
return (
<form className="flex flex-col gap-y-2"›
<input type="text" name="firstName" placeholder="first name" className="px-4 py-2" onChange={handleChange} />
<input type="text" name="lastName" placeholder="last name" className="px-4 py-2" onChange={handleChange} />
<input type="text" name="email" placeholder="email" className="px-4 py-2" onChange={handleChange}/>
<input type="text" name="password" placeholder="password" className="px-4 py-2" onChange={handleChange}/>
<input type="text" name="address" placeholder="address" className="px-4 py-2" onChange={handleChange}/>
<input type="text" name="zipCode" placeholder="zip code" className="px-4 py-2" onChange={handleChange}/>
<button className="bg-blue-500 px-4 py-2">Submit</button>
</form>
);
}
No comments:
Post a Comment