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;
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.
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;