Using React, we can take the user interface, and split them into independent uniits called components. And it's the type & properties of the components that can describe how the user interface looks and behave
A hook is a function provided by React that lets you hook into react features from your function components
You should not use hooks inside a condition, it has to be at the top level of the component
useState
In traditional approach, state is an object has multiple fields. In order to access the state, we need to use this.state.something
- With useState, we declare 2 state variables for `name` & `surname` and whenever we call `setName`, `setSurname`, we tell react to re-render this component, just like if we say `setState` >> the next time react renders the component, it passes the current `name` & `surname` to our component. We can access these state variables directly without using `this.state`
```js
const [name, setName] = useState('Mary');
const [surname, setSurname = usetState('Poppins');
function handleNameChange(e) {
setName(e.target.value);
}
function handleSurnameChange(e) {
setSurname(e.target.value);
}
useContext
Context is kind of like global variables for a subtree. It is useful for things like read the current theme, language,.. It is useful to avoid passing everything through props
In traditional approach
import { ThemeContext, LocaleContext } from './context';
render() {
return (
{theme => (
)}
{locale => (
{ locale }
)}
)
}
```
- With useContext, we can get the global variables `theme` & `locale` without nested code
```js
import { ThemeContext, LocaleContext } from './context';
const theme = useContext(ThemeContext);
const locale = useContext(LocaleContext);
return (
{locale}
)
```
### useEffect
- used to perform lifecycle methods such as perform some side effects (firing off requests, performing DOM mutation, interfacing with browser's APIs,..). They should be performed during rendering since the component is not rendered yet
- With traditional approach, we need to repeat logic in both componentDidMount & componentDidUpdate to keep them be consistent since they fired at different times
```js
componentDidMount() {
document.title = this.state.name + ' ' + this.state.surname;
}
componentDidUpdate() {
document.title = this.state.name + ' ' + this.state.surname;
}
```
- With useEffect, the effects are consistent by default. If we want to opt out of that, we can use
```js
useEffect(() => {
document.title = name + ' ' + surname;
})
```
- In traditional approach, if we want to subscribe to browser API such as we want to update the state in response to the changes of browser's size => We need to declare a new variable in the state object, we use `componentDidMount` to subscribe an the event listener, and use `componentWillUnmount` to unsubscribe. We also need to bind function `handleResize` to update the width
```js
constructor(props) {
this.state = {
name: "Mary",
surname: "Poppins"
width: window.innerWidth;
}
this.handleNameChange = this.handleNameChange.bind(this);
this.handleSurnameChange = this.handleSurnameChange.bind(this);
this.handleResize = this.handleResize.bind(this);
}
componentDidMount() {
document.title = this.state.name + ' ' + this.state.surname;
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
handleResize() {
this.setState({
width: window.innerWidth;
})
}
render() {
return (
{theme => (
{this.state.width}
)}
)
}
```
- With useEffect
```js
useEffect(() => {
document.title = name + ' ' + surname;
})
const [width, setWidth] = useState(window.innerWidth);
const handleResize = () => { setWidth(window.innerWidth) };
useEffect(() => {
window.addEventListener('resize', this.handleResize);
// Unsubscribed
return () => {
window.removeEventListener('resize', this.handleResize);
}
})
```
### custom Hook
- we can extract the window's useEffect hook to a custom hook
```js
const width = useWindowWidth();
function useWindowWidth () {
const [width, setWidth] = useState(window.innerWidth);
const handleResize = () => { setWidth(window.innerWidth) };
useEffect(() => {
window.addEventListener('resize', this.handleResize);
// Unsubscribed
return () => {
window.removeEventListener('resize', this.handleResize);
}
})
return width;
}
### useRef
### useParams
### useHistory
Reference: React Conf 2018
What is React Hooks?
useState
this.state.something
handleNameChange(e) { this.setState({ name: e.target.value; }) }
handleSurnameChange(e) { this.setState({ surname: e.target.value; }) }
useContext
render() { return (