- 
                Notifications
    
You must be signed in to change notification settings  - Fork 4
 
Open
Description
最近一直在维护 React 中文文档,重点维护了 Hook 相关的部分,因此总结下 Hook 相关的内容以及自己的一些看法。
注:看了很多文章大家都直接使用了英文的 Hooks,这里想纠正一下,建议大家以后直接使用 Hook 即可。
Hook 简介
简单来讲,Hook 的意义:
- 在函数组件中可以使用 state 及 React 其他特性的一种方式,旨在复用代码逻辑;
 - 替换掉 HOC 及 
Render Props带来的冗余代码,以及对组件结构带来的破坏性; - 降低 React 学习成本,去除学习 JavaScript 中 class 带来的困扰,如函数的 
this绑定问题,不稳定语法提案,以及生命周期带来困扰; - 不用再纠结用哪种组件形式,直接使用函数组件即可。
 
注:
- class 组件不会被替换掉,无需担心之前代码需要重写的问题。
 - Hook 只能放在函数的顶层。
 
Hook 的简单使用
系统提供的 Hook 有以下几种:
- 基础 Hook
- useEffect 为组件添加 effect 特性
 - useState 为组件添加 State 特性
 - useContext 为组件添加 Context 特性
 
 - 额外 Hook
- useReducer 类似于 Redux
 - useRef
 - useLayoutEffect
 - useImperativeHandle
 - useCallback
 - useMemo
 - useDebugValue
 
 
useState()
state 在函数组件中的使用:
const [value, setValue] = useState('');useEffect()
简易的验证码倒计时的例子:
const [count, setCount] = useState(60);
useEffect(() => {
  let interval = setInterval(() => {
    setCount(count => count - 1);
  }, 1000);
  return () => {
	clearInterval(interval);
  };
}, []);使用 Hook 编写 TodoList
TodoList 是大家学习新内容的首选项目,话不多说,直接开始。
环境配置
使用 create-react-app 搭建环境,并引入 ant-design:
$ create-react-app react-hook-todo && cd react-hook-todo
$ yarn add antd修改 App.js 的代码:
import React, { Component } from 'react';
import Button from 'antd/lib/button';
import './App.css';
class App extends Component {
  render() {
    return (
      <div className="App">
        <Button type="primary">添加 Todo</Button>
      </div>
    );
  }
}
export default App;修改 App.css 的样式:
@import '~antd/dist/antd.css';
.App {
  text-align: center;
}
...开启 Todo 之旅
首先,修改下组件结构,将 App 组件改为函数式,并添加一个 Input 组件:
import React from 'react';
import Button from 'antd/lib/button';
import Input from 'antd/lib/input';
import './App.css';
function App() {
  return (
    <div className="App">
      <div className="Background">
        <Input className="my-input" style={{width: 200, marginRight: 10}} placeholder="请输入 Todo"></Input>
        <Button type="primary">添加 Todo</Button>
      </div>
    </div>
  );
}
export default App;接下来,当输入框输完内容,点击添加 Todo,会添加一个 Todo 到列表中。因此,我们需要 state 来存储当前输入的 Todo:
import React, { useState } from 'react';
function App() {
  const [todo, setTodo] = useState('');
  return (
    <div className="App">
      <div className="Background">
        <Input value={todo} className="my-input" onChange={(e) => setTodo(e.target.value)} style={{width: 200, marginRight: 10}} placeholder="请输入 Todo"></Input>
        <Button type="primary">添加 Todo</Button>
      </div>
    </div>
  );
}  然后,需要将每次输入的 Todo 保存在列表中,因此需要再次引入一个 TodoList 的 state。
并且每次输入完成,点击添加后,应该清除之前的 todo 的值:
function App() {
  const [todo, setTodo] = useState('');
  const [todoList, setTodoList] = useState([]);
  return (
    <div className="App">
      <div className="Background">
        <Input value={todo} className="my-input" onChange={(e) => setTodo(e.target.value)} style={{width: 200, marginRight: 10}} placeholder="请输入 Todo"></Input>
        <Button type="primary" onClick={() => setTodoList(todoList => {
          setTodo('');
          return [...todoList, todo];
        })}>添加 Todo</Button>
      </div>
    </div>
  );
}最后,我们使用一个列表来展示所生成的 TodoList:
创建 TodoList 组件:
import React from 'react';
function TodoList(props) {
  let { list } = props;
  return (
    <div className="todo-list">
      <ul>
        {
          list.map((item, index) => {
            return <li key={index}>{item}</li>
          })
        }
      </ul>
    </div>
  );
}
export default TodoList;引入 TodoList 组件,并传入我们生成的 todoList 的 state:
import TodoList from './components/TodoList';
function App() {
  const [todo, setTodo] = useState('');
  const [todoList, setTodoList] = useState([]);
  return (
    <div className="App">
      <div className="Background">
        <Input value={todo} className="my-input" onChange={(e) => setTodo(e.target.value)} style={{width: 200, marginRight: 10}} placeholder="请输入 Todo"></Input>
        <Button type="primary" onClick={() => setTodoList(todoList => { 
          setTodo('');
          return [...todoList, todo];
        })}>添加 Todo</Button>
      </div>
      <TodoList list={todoList}></TodoList>
    </div>
  );
}总结
上述使用了 useState 巧妙的实现了 TodoList 的效果。总的来说,Hook 还是非常便捷的。下一节,我们将继续完善这个 TodoList,加入更多的 Hook。
参考
Metadata
Metadata
Assignees
Labels
No labels