I am trying to make an app that receives an ID for a product from the user, then finds the product from the database and updates the product on the screen. I receive the ID by using an useState
and an input box. The GetProduct
component gets called, and the ID is passed to it through Props
. It fetches the product by that ID (using an useEffect
) and returns that product.
The problem:
The useEffect
fetches the product once when the app starts (when the ID is still empty), and when the ID gets updated, the product won't update again.
App.tsx:
function App() {
const [id, setId] = useState("")
const onChangeHandler = (event: { target: { value: React.SetStateAction<string> } }) => {
setId(event.target.value)
}
return(
<div className="App">
<input
type="text"
name="name"
onChange={onChangeHandler}
value={id}
/>
<GetProduct id={id}></GetProduct>
</div>
)
GetProduct
Component:
import { Product } from "../api/dto/product.dto"
import productService from "../services/product.service"
interface Props {
id: string
}
export const GetProduct: React.FC<Props> = (props) => {
const [product, setProduct] = useState<Product>()
useEffect(() => {
async function fetchOne() {
const response = await productService.getOne(props.id)
setProduct(response.data)
}
fetchOne()
}, [])
return (
<>
<div>
{product?.title}, {product?.description}, {product?.price}
</div>
</>
)
}
CodePudding user response:
You can add props.id
to dependency array so it would rerun on id change. Having an empty dependency array makes it run only once.
useEffect(() => {
async function fetchOne() {
const response = await productService.getOne(props.id)
setProduct(response.data)
}
fetchOne()
}, [props.id])