8bitzz / blogs

0 stars 0 forks source link

Useful Hooks #17

Open 8bitzz opened 3 years ago

8bitzz commented 3 years ago

Reference: React Conf 2018

What is React Hooks?

useState

handleNameChange(e) { this.setState({ name: e.target.value; }) }

handleSurnameChange(e) { this.setState({ surname: e.target.value; }) }

- 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

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