-
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