all articles

A look at React Hooks

2018-12-09 @sunderls

js react





react 在下一个版本 16.7 中会出现 Hooks 的一个东西,一直没时间看,今天在热海参加 workshop 终于有时间看看了。

https://reactjs.org/docs/hooks-intro.html

直接上官方例子吧。

import { useState } from "react";

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

哦?如果不用 hooks 的话,大概我们会这么写吧

import { Component } from "react";

class Example extends Component {
    state = {
        count: 0
    }

    setCount = (count) => {
        this.setState{{count}}
    }

    render() {
        const {count} = this.state
        return <div>
            <p>You clicked {count} times</p>
            <button onClick={() => this.setCount(count + 1)}>Click me</button>
        </div>
    }
}

嗯,确实写法上面简介了许多。

hooks 尝试解决的问题如下:

  1. It’s hard to reuse stateful logic between components

通常要充用 logic 的话,估计 create 一个新的 class,然后 extend 吧。对于某些问题就用 HOC 包裹一层,

比如如果要 lazy loading 一个 component,就创建一个 Lazy 把 componennt 保住,

简单的例子就是 react-router 中的withRouterwithRouter(component)返回了一个加入了功能的 component。

但是 HOCyou 的时候不方便,因为是层级结构,包住的,经常遇到一些问题就是一个 prop 传递不进去之类的,如果我要用 3 个功能,

withA(withB(withC(component))。。嗯。

Hooks 把 state logic 从 component 层级中分开了。

嗯,还是没有具体的意向。

  1. Complex components become hard to understand

嗯,这个是的。

一个是 component 越来越复杂,本身 didMount/didUpdate 之类的包含了过多的逻辑,无法拆开。 另一个是用 redux(我现在不用 redux)等 state library 会让逻辑过于分散难以理解。

hooks 可以通过将 state 相关的拆分成小规模的 function,自由组合。

嗯,还是没有具体的意向。

  1. Classes confuse both people and machines

class 不给力?暂时没有感觉,总之 Hooks 可以减少 class 的使用。

State Hook

之前的例子就是 state hook,用来管理 state。

const [count, setCount] = useState(0);
//     state值  setter      初始值

多个 state 的话?

const [age, setAge] = useState(42);
const [fruit, setFruit] = useState("banana");
const [todos, setTodos] = useState([{ text: "Learn Hooks" }]);

如此,一个 function 就有了 state 能力,所以叫做 functional component. 其中 state 逻辑跑在 class 之外的逻辑。

注意的是 第一个返回值 count是值,直接可以用。所以是<p>You clicked {count} times</p>

那如何在不同的 component 里面分享 state 呢?

直接 export?

Effect Hook

componentDidMount componentDidUpdate componentWillUnmount会被替换为 useEffect

function Example() {
  const [count, setCount] = useState(0);

  // useEffect中的function将在每一次render的时候执行。
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return <div />;
}

被 unmount 的时候执行的方法是作为 useEffect 的返回值来的。

useEffect(() => {
  ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
  // unmount的时候执行这个
  return () => {
    ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
  };
});

啊。。好晕,有点不太明白了,有兴趣的同学查看一下文档吧:https://reactjs.org/docs/hooks-reference.html

问题

为什么要这样做?

可以从代码看出来,用useState的话,state 的逻辑就和 UI 彻底分开了。相当于 state 的管理只是 ui render 的一个副作用,

这看上去很好,比如 dom 操作等,也是很好的。

当 state 更新的时候,react 是怎么知道哪个 compoenent 用到了的呢?

react 会在内部存储用到的 state 信息。具体看这里: https://reactjs.org/docs/hooks-faq.html#how-does-react-associate-hook-calls-with-components

总结

还是有点晕,有时间再看看



如果觉得有帮助到你的话,
欢迎支付宝donate