3.6 Hook

UseEffect

沒有使用Hook的寫法:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    };
    this.incrementCounter = this.incrementCounter.bind(this);
  }
  componentDidMount() {
    this.setState({
      counter: 10
    });
  }

  componentWillUnmount() {
    this.setState({
      counter: 0
    });
  }
  incrementCounter() {
    this.setState(state => ({
      counter: state.counter + 1
    }));
  }
  render() {
    return (
      <h1 onClick={this.incrementCounter}>
        Hello, {this.props.name}
        {this.state.counter} times
      </h1>
    );
  }
}

useEffect方法寫,出乎意料簡潔:

function App(props) {
  const [counter, setCounter] = useState(0);
  useEffect(() => {
    setCounter(counter => 10);
    return () => {
      setCounter(counter => 0);
    };
  }, []);
  return (
    <h1 onClick={() => setCounter(counter => counter + 1)}>
      Hello, {props.name}
      {counter} times
    </h1>
  );
}
  • 原本應在componentDidMount 的是 setCounter(counter=>10)

  • 原本應在componentWillUnmount 的是 setCounter(counter=>0)

componentDidUpdate呢? 有趣的是,上面並沒有對應 componentDidUpdate的地方,因為在useEffect第二個參數,有一個empty array。第二個參數是此effect的dependency,React會儲起每次這個array的數值,如果在下一次update的時候發現這個array改變了,就代表了 這個effect需要重新運行。由於一個empty array永遠都是一樣,所以我們這個useEffect只會運行一次!如果沒有了第二個參數,那就變成了 componentDidUpdate +componentDidMount了。

useEffect(()=>{
    // componentDidMount is here!
    // componentDidUpdate is here!
    setCounter(counter=> 10);
    return ()=>{
        // componentWillUnmount is here!
        setCounter(counter=>0)
    }
});

Last updated