I'm trying to solve a React problem on testdome.
This is the task:
The Message component contains an anchor element and a paragraph below the anchor. Rendering of the paragraph should be toggled by clicking on the anchor element using the following logic:
At the start, the paragraph should not be rendered.
After a click, the paragraph should be rendered.
After another click, the paragraph should not be rendered.
Finish the Message component by implementing this logic.
This is the solution:
// React is loaded and is available as React and ReactDOM
// imports should NOT be used
class Message extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false
};
}
clickHandler = (event) => {
event.preventDefault();
this.setState({
visible: !this.state.visible
});
}
render() {
return (<React.Fragment>
<a onClick={this.clickHandler} href="#">Want to buy a new car?</a>
{ this.state.visible && <p>Call 11 22 33 44 now!</p>}
</React.Fragment>);
}
}
document.body.innerHTML = "<div id='root'> </div>";
const rootElement = document.getElementById("root");
ReactDOM.render(<Message />, rootElement);
console.log("Before click: " rootElement.innerHTML);
document.querySelector("a").click();
console.log("After click: " rootElement.innerHTML);
I want to do the same with useState Hook. Here is my code:
// React is loaded and is available as React and ReactDOM
// imports should NOT be used
class Message extends React.Component {
const [show, setShow] = useState(false);
const toggleVisibility = () => {
setShow(!show);
}
render() {
if(show) {
return (<React.Fragment>
<a onClick={toggleVisibility} href="#">Want to buy a new car?</a>
<p>Call 11 22 33 44 now!</p>
</React.Fragment>);
} else {
return (<React.Fragment>
<a onClick={toggleVisibility} href="#">Want to buy a new car?</a>
</React.Fragment>);
}
}
}
document.body.innerHTML = "<div id='root'> </div>";
const rootElement = document.getElementById("root");
ReactDOM.render(<Message />, rootElement);
console.log("Before click: " rootElement.innerHTML);
document.querySelector("a").click();
console.log("After click: " rootElement.innerHTML);
This is the Output:
Run OK, but 3 out of 3 test cases failed.
Line 5: SyntaxError: unknown: Unexpected token (5:8)
3 | class Message extends React.Component {
4 |
> 5 | const [show, setShow] = useState(false);
| ^
6 |
7 | const toggleVisibility = () => {
8 | setShow(!show);
Your score is 0% :(
Why does it not work? is it not allowed to use hooks in class components? if thats not possible, how can I change the class component into a function component?
CodePudding user response:
You cannot use hooks in class components, only for functional components. You could refactor your Message component into a functional component like the following:
export const Message = () => {
const [show, setShow] = useState(false);
const toggleVisibility = () => {
setShow(!show);
}
if(show) {
return (
<React.Fragment>
<a onClick={toggleVisibility} href="#">Want to buy a new car?</a>
<p>Call 11 22 33 44 now!</p>
</React.Fragment>
);
} else {
return (
<React.Fragment>
<a onClick={toggleVisibility} href="#">Want to buy a new car?</a>
</React.Fragment>
);
}
}
CodePudding user response:
You cannot use useState()
hook in a Class based component. To do so switch to a functional based component.
You can create a functional component as below