Stack Overflow Asked by Peppa Box on January 28, 2021
I would like to render the return from the else if statement.
Is there a way to have the images render within the tags?
I would like to show a different image depending on the result returned from the API
export default function GetDieResult() {
const [dieRollResult, setDieRollResult] = useState(1);
const whichDieImageToDisply = (rollResult ) => {
if (rollResult === 1) {
return <img className="die" src={d1} alt="A die displaying 1" />;
} else if (rollResult === 2) {
return <img className="die" src={d2} alt="A die displaying 2" />;
} else if (rollResult === 3) {
return <img className="die" src={d3} alt="A die displaying 3" />;
} else if (rollResult === 4) {
return <img className="die" src={d4} alt="A die displaying 4" />;
} else if (rollResult === 5) {
return <img className="die" src={d5} alt="A die displaying 5" />;
} else if (rollResult === 6) {
return <img className="die" src={d6} alt="A die displaying 6" />;
}
};
const checkResponse = (response) => {
if (!response.ok) throw new Error(`Network error: ${response.status}`);
return response.json();
};
const rollDie = () => {
fetch("https://rolz.org/api/?d6.json")
.then(checkResponse)
.then((data) => {
setDieRollResult(data.result);
whichDieImageToDisply();
console.log(whichDieImageToDisply(data.result))
});
};
useEffect(() => {
rollDie();
}, [dieRollResult]);
console.log(dieRollResult);
return (
<main>
<img src={d1} alt="A die displaying 1" className="die" />
</main>
);
}
If I were you, I would do some refactoring on the code and simplify it a bit.
First, I would move the fetching to the useEffect
hook and make the dependency array empty. This way it will only make the request to the API once after rendering the component. Then, I would create a status
state so I can easier track in which status the component is currently at. This then allows me to render the correct image based on the dieRollResult
that got fetched from the API. Also, you can simply call the dieImage()
function in the JSX
that will then render the correct image based on dieRollResult
and because we are using status
here, the dieImage()
function will be called only when you have fetched the data from the API. Until then, it will show you a loading text.
function GetDieResult() {
const [dieRollResult, setDieRollResult] = useState(1);
const [status, setStatus] = useState("idle");
const dieImage = () => {
if (dieRollResult === 1) {
return <img className="die" src={d1} alt="A die displaying 1" />;
} else if (dieRollResult === 2) {
return <img className="die" src={d2} alt="A die displaying 2" />;
} else if (dieRollResult === 3) {
return <img className="die" src={d3} alt="A die displaying 3" />;
} else if (dieRollResult === 4) {
return <img className="die" src={d4} alt="A die displaying 4" />;
} else if (dieRollResult === 5) {
return <img className="die" src={d5} alt="A die displaying 5" />;
} else if (dieRollResult === 6) {
return <img className="die" src={d6} alt="A die displaying 6" />;
}
};
useEffect(() => {
setStatus("fetching");
fetch("https://rolz.org/api/?d6.json").then(async (res) => {
if (!res.ok) {
setStatus("failed");
throw new Error(`Network error: ${res.status}`);
}
const { result } = await res.json();
setDieRollResult(result);
setStatus("processed");
});
}, []);
return (
<main>
{status === "processed" ? (
dieImage()
) : (
<p style={{ color: "blue" }}>loading...</p>
)}
</main>
);
}
Correct answer by Mantas Astra on January 28, 2021
import React from "react";
export default function Img (props) {
const [myPic, setMyPic] = React.useState("");
React.useEffect(() => {
fetch(props.url)
.then(res=>res.blob())
.then(pic =>{
const auxUrl = URL.createObjectURL(pic);
setMyPic(auxUrl);
return function () {
URL.revokeObjectURL(auxUrl);
}
})
}, [props.url]);
return (
<img src={myPic} />
)
}
Answered by Ernesto on January 28, 2021
You can call function from return block. whichDieImageToDisply()
.But if that function needs to take state, or needs to be defined inside component, and every render will create function again. You might need to wrap it with useCallback etc; but i will provide an alternative way, i think better and cleaner way, via enums.
Inside your return block you can use this; you wont need a whichDieImageToDisply function.
{
{
1: <img className="die" src={d1} alt="A die displaying 1" />;,
2: <img className="die" src={d2} alt="A die displaying 2" />,
3: <img className="die" src={d3} alt="A die displaying 3" />,
4: <img className="die" src={d4} alt="A die displaying 4" />;,
5: <img className="die" src={d5} alt="A die displaying 5" />,
6: <img className="die" src={d6} alt="A die displaying 6" />,
}[dieRollResult]
}
More: https://www.robinwieruch.de/conditional-rendering-react
Answered by Emre A on January 28, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP