Reputation: 13
I am not sure why my Button dosen't work, I use useState and useEffect
here is my code:
import React, { useState, useEffect } from "react";
// import Timeout from "await-timeout";
import axios from "axios";
export default function Dogs() {
const [dog, set_Dog] = useState(" ");
console.log({ dog });
useEffect(() => {
async function getFetch() {
const res = await axios.get("https://dog.ceo/api/breeds/image/random");
const {
data: { message },
} = res;
console.log("Got back", message);
set_Dog(message);
}
getFetch();
}, []);
function output() {
set_Dog(dog);
// console.log(set_Dog({ dog }));
}
return (
<div>
<h2>If you like Dogs,{dog} Press Button</h2>
<button onClick={output}>Click me</button>
{dog}
<img src={dog} />
</div>
);
}`
when I click on the button the image be disappeared, I want to show a new image of the dog without refresh my browser
Upvotes: 1
Views: 79
Reputation: 184
Try :
onClick={() => output()}
Like that it only renders when you clicking on the button and not everytime the component re-render.
Upvotes: 0
Reputation: 11
You can use useRef to keep a reference to your function after fetching the first image.
const click_ref = React.useRef(null);
useEffect(() => {
async function getFetch() {
const res = await axios.get("https://dog.ceo/api/breeds/image/random");
const {
data: { message },
} = res;
console.log("Got back", message);
set_Dog(message);
}
getFetch();
click_ref.current = getFetch;
}, []);
<button onClick={() => click_ref.current()}>Click me</button>
Upvotes: 1
Reputation: 6837
The value of dog
which is being set on the in the function output
never changes because of stale closure.
Because you want to populate the state on mount
and also change it when user clicks on a button, you have to create the function which calls the API in the function scope and memoize it with useCallback
, the same function can be passed to the onClick
. For example,
export default function Dogs() {
const [dog, set_Dog] = useState("");
console.log({ dog });
const getDogPic = useCallback(async () => {
const res = await axios.get("https://dog.ceo/api/breeds/image/random");
const {
data: { message }
} = res;
console.log("Got back", message);
set_Dog(message);
}, []);
useEffect(() => {
getDogPic();
}, []);
return (
<div>
<h2>If you like Dogs,{dog} Press Button</h2>
<button onClick={getDogPic}>Click me</button>
{dog}
<img src={dog} alt={"dog-pic"} />
</div>
);
}
Working demo in codesandbox
Read more about stale-closures
Upvotes: 1