React Class功能與Hooks等效項


React Class功能與Hooks等效項

https://medium.com/soluto-engineering/react-class-features-vs-hooks-equivalents-745368dafdb3

I gave a talk during a recent meetup at Soluto HQ — Intro to React Hooks.
While preparing for the presentation, I fell completely in love with Hooks.
Although I was skeptical at first glance, I quickly realized how easy it is to use them and how they make perfect sense.
You can really tell how much thought was put into the API and how it solves real life problems.
You can find a video of my talk attached to this post (Hebrew only… Sorry!).
In my talk I explained why we need Hooks, how they work, went over the core Hooks (useState, useEffect, useRef and useContext) and showed how to convert some of the class features into Hooks.
I also covered some other new features — memo, lazy and Suspense.
If you don’t speak Hebrew or just prefer reading over watching, I made a TL:DW (kind of a cheat sheet) on class features vs. Hooks. Enough intros… Let’s jump right to business!

最近在Soluto HQ的一次聚會上,我做了一個演講-React Hooks簡介。
在准備演示文稿時,我完全愛上了Hooks。
盡管乍一看我對此表示懷疑,但我很快意識到使用它們很容易,並且它們具有完美的意義。
您真的可以說出API投入了多少思想,以及它如何解決現實生活中的問題。
您可以在這篇文章中找到我的演講視頻(僅希伯來語……對不起!)。
在我的演講中,我解釋了為什么我們需要Hook,它們如何工作,遍歷了核心Hook(useState,useEffect,useRef和useContext),並展示了如何將某些類功能轉換為Hook。
我還介紹了其他一些新功能-備忘錄,懶惰和掛起。
如果您不會講希伯來語,或者只是喜歡看書而不是看書,那么我對課堂功能vs. Hooks做了TL:DW(備忘單)。 足夠的介紹…讓我們開始吧!

Class features vs. Hooks equivalents

State

//Class
class CounterButton extends Component {
    constructor() {
        super();
        this.state = {
            count: 0
        }
    }
    render() {
        return <button onClick={() => this.setState({ count: this.state.count + 1 })}>
            { this.state.count }
         </button>
    }
}

//Hooks
const CounterButton = props => {
    const [count, setCount] = useState(0);

    return <button onClick={() => setCount(count + 1)}>
            { count }
    </button>
}

ComponentDidMount

//Class
componentDidMount() {
    console.log('I just mounted!');
}

//Hooks
useEffect(() => {
    console.log('I just mounted!');
}, [])

ComponentWillUnmount

//Class
componentWillUnmount() {
    console.log('I am unmounting');
}

//Hooks
useEffect(() => {
    return () => console.log('I am unmounting');
}, [])

ComponentWillReceiveProps \ ComponentDidUpdate

//Class
componentWillReceiveProps(nextProps) {
    if (nextProps.count !== this.props.count) {
        console.log('count changed', nextProps.count);
    }
}

//Hooks
useEffect(() => {
    console.log('count changed', props.count);
}, [props.count])


//Class
componentDidUpdate() {
    console.log('Just updated..');
}

//Hooks
useEffect(() => {
    console.log('Just updated...');
})

DOM refs

//Class
class InputWithFocus extends React.Component {
    constructor() {
        super();
        this.inputRef = null;
    }
    render() {
        return <>
            <input ref={inputRef => { this.inputRef = inputRef }} />
            <button onClick={() => this.inputRef.focus()}>
                Focus the input
            </button>
        </>
    }
}
//Hooks
const InputWithFocus = (props) => {
    const inputRef = useRef();
    return <>
        <input ref={inputRef} />
        <button onClick={() => inputRef.current.focus()}>
            Focus the input
        </button>
    </>
}

this.myVar

useRef has another cool usage besides DOM refs, it is also a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.
Handy, for example, to keep an interval id:

const Timer = (props) => {
    const intervalRef = useRef();

    useEffect(() => {
        const id = setInterval(() => {
            // ...
        });
        intervalRef.current = id;
        return () => {
            clearInterval(intervalRef.current);
        };
    });
}

Comparing with the previous state\props

Some lifecycle method, like componentDidUpdate, provide the previous state and props.
If you really need the previous values for your Hooks, this can be imitated the following way (using yet again our good friend — useRef):

const Counter = props => {
    const [count, setCount] = useState(0);

    const prevCountRef = useRef();
    useEffect(() => {
        prevCountRef.current = count;
    });
    const prevCount = prevCountRef.current;

    return <h1>Now: {count}, before: {prevCount}</h1>;
}

ShouldComponentUpdate

We gonna use memo for this one, while this is not a Hook, it’s still part of the class-to-functional-component migration plan:

//Class
shouldComponentUpdate(nextProps) {
    return nextProps.count !== this.props.count
}

//memo
import React, { memo } from 'react';

const MyComponent = memo(
    _MyComponent, 
    // Notice condition is inversed from shouldComponentUpdate
    (prevProps, nextProps) => nextProps.count === prevProps.count

And that is React Hooks in a nutshell. I hope you will find this helpful when writing your next functional component.
Needless to say (but I’ll say it anyway), there are a whole lot more interesting and cool ways to use Hooks. I urge you to read the awesome overview the React team posted. Don’t miss out the FAQ section!
Last but not least, here’s me in my meetup video about React Hooks.
Watch, Like, Subscribe 😉


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM