React State Hook

Hooks in React JS let you use state and other React features without writing a class.

What is a Hook?
A Hook is a special function that lets you “hook into” React features. For example, useState is a Hook that lets you add React state to function components. We’ll learn other Hooks later.

When would I use a Hook?
If you write a function component and realize you need to add some state to it, previously you had to convert it to a class. Now you can use a Hook inside the existing function component. We’re going to do that right now!

Let's look at the sample below:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Button } from 'smart-webcomponents-react/button';
import { Input } from 'smart-webcomponents-react/input';

const MyComponent: React.FC = () => {
	const [name, setName] = useState('');

	const onShowNameClicked = () => {
		alert('Name is: ' + name);
	};

	const onNameChanged = (e: any) => {
		setName(e.target.value);
	};

	return (
		<div>
			<Input placeholder="Enter a name" value={name} onKeyUp={onNameChanged} onChange={onNameChanged} />
			<br />
			<div>
				Name is {name}
			</div>
			<Button onClick={onShowNameClicked}>
				<span>Show Name</span>
			</Button>
		</div >
	)
}

class App extends React.Component {
	render() {
		return (
			<MyComponent />
		)
	}
}

ReactDOM.render(<App />, document.querySelector("#root"));

export default App;


Class Example

If you used classes in React before, this code should look familiar:
import React from "react";
import ReactDOM from "react-dom";
import { Button } from 'smart-webcomponents-react/button';
import { Input } from 'smart-webcomponents-react/input';

class MyComponent extends React.Component<{}, { name: string }> {
	constructor(props: any) {
		super(props);
		this.state = {
			name: ''
		};
	}

	onShowNameClicked = () => {
		alert('Name is: ' + this.state.name);
	};

	onNameChanged = (e: any) => {
		this.setState({ name: e.target.value });
	};

	render() {
		return (
			<div>
				<Input placeholder="Enter a name" onKeyUp={this.onNameChanged} onChange={this.onNameChanged} />
				<br />
				<div>
					Name is {this.state.name}
				</div>
				<Button onClick={this.onShowNameClicked}>
					<span>Show Name</span>
				</Button>
			</div >
		)
	}
}

class App extends React.Component {
	render() {
		return (
			<MyComponent />
		)
	}
}

ReactDOM.render(<App />, document.querySelector("#root"));

export default App;

The state starts as { name: "" }, and we update state.name when the user types into an input by calling this.setState().

Declaring a state

In a class, we initialize the name state to "" by setting this.state to { name: "" } in the constructor:
	constructor(props: any) {
		super(props);
		this.state = {
			name: ''
		};
	}
In a function component, we have no this, so we can’t assign or read this.state. Instead, we call the useState Hook directly inside our component:
const [name, setName] = useState('');

useState do: useState declares a “state variable”. Our variable is called name but we could call it anything else. This is a way to “preserve” some values between the function calls — useState is a way to use the exact same capabilities that this.state provides in a class. Normally, variables “disappear” when the function exits but state variables are preserved by React.
useState args: The only argument to the useState() Hook is the initial state. Unlike with classes, the state doesn’t have to be an object. We can keep a number or a string if that’s all we need. In our example, we just want a name for the user entered name in the input, so pass "" as initial state for our variable. (If we wanted to store two different values in state, we would call useState() twice.)
useState returns: useState returns a pair of values: the current state and a function that updates it. This is why we write const [name, setName] = useState(). This is similar to this.state.name and this.setState in a class, except you get them in a pair.

Reading State

When we want to display the current name in a class, we read this.state.name:
Name is {this.state.name}
In a function, we can use name directly:
Name is {name}

Updating State

In a class, we need to call this.setState() to update the name state:
onNameChanged = (e: any) => {
	this.setState({ name: e.target.value });
};
In a function, we already have setName and name as variables:
const onNameChanged = (e: any) => {
	setName(e.target.value);
};

Example using state variables

Using Multiple State Variables

Declaring state variables as a pair of [something, setSomething] is also handy because it lets us give different names to different state variables if we want to use more than one:
  const [firstName, setFirstName] = useState('John');
  const [lastName, setLastName] = useState('Doll');