I'm new to React and have a 2 part question:
I'm trying to print data from an API in React using the following code but I am not getting any output. What's the issue?
After the Category and Question prints, I want the answer to be hidden. It must only be revealed when the button is clicked. How do I achieve this?
class Question extends React.Component { constructor(props) { super(props); this.state = { category: [], question: [], answer: [], revealed: [false] }; } componentDidMount() { axios({ url: "http://jservice.io/api/random?count=1", method: "GET" }) .then((result) => { this.setState({ category: result.category, question: result.question, answer: result.answer }); }); } render() { const { category } = this.state; const { question } = this.state; const { answer } = this.state; return( <div> <div> {category} </div> <div> {question} </div> <div> {answer} </div> <button type="button" onClick={() => this.answer.setState(true)}>Reveal answer</button> </div> ); }}export default Question;
CodePudding user response:
This code needs a lot of refactoring.
This will definitely do it:
import React, { useState, useEffect } from "react";
const Question = () => {
const [question, setQuestion] = useState();
const [category, setCategory] = useState({title: "default title"});
const [answer, setAnswer] = useState();
const [showAnswer, setShowAnswer] = useState(false);
useEffect(() => {
axios({
url: "http://jservice.io/api/random?count=1",
method: "GET"
})
.then((result) => {
setQuestion(result[0].question);
setAnswer(result[0].answer);
setCategory(result[0].category);
});
}, []);
return (
<div>
<div>Category: {category.title}</div>
<div>Question: {question}</div>
<div>Answer: {showAnswer ? answer : null}</div>
<div><button onClick={() => setShowAnswer(true)}>Reveal Answer</button></div>
</div>
);
}
export default Question;
In the above i used useEffect for lifecycle events like componentDidMount and useState hook for managing state in this functional component.
CodePudding user response:
You can create a function to update revealed
and then you can pass by props revealed
to create the ternary {revealed ? answer : ""}
If this is a project of yours, I would recommed to start using ReactJS with hooks!
class Question extends React.Component {
constructor(props) {
super(props);
this.state = {
category: [],
question: [],
answer: [],
revealed: false
};
// Binding this keyword
this.updateState = this.updateState.bind(this)
}
updateState(){
// Changing state
this.setState({
revealed: true,
})
}
componentDidMount() {
axios({
url: "http://jservice.io/api/random?count=1",
method: "GET"
})
.then((result) => {
this.setState({
category: result.category,
question: result.question,
answer: result.answer
});
});
}
render() {
const { category, question, answer, revealed } = this.state;
return(
<div>
<div>
{category}
</div>
<div>
{question}
</div>
<div>
{revealed ? answer : ""}
</div>
<button type="button" onClick={this.updateState}>Reveal answer</button>
</div>
);
}}
export default Question;