# react-selfdefine-hook
**Repository Path**: cai-lunduo/react-selfdefine-hook
## Basic Information
- **Project Name**: react-selfdefine-hook
- **Description**: react的自定义hook使用
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-05-30
- **Last Updated**: 2021-05-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
### 自定义Hook(补充)
自定义hook可以让我们将组件逻辑提取到一个可重复利用的组件内。
这里会有两个案例讲解自定义hook的使用
**第一个简单的例子**:
```react
import {useState, useEffect} from 'react'
function Comp() {
let [num, setNum] = useState(0)
useEffect(() => {
setTimeout(() => {
setNum(++num)
}, 2000)
}, [])
return (
Comp -- {num}
)
}
function App() {
return (
);
}
export default App;
```
如上所示,我们可以将`Comp`组件的
```react
let [num, setNum] = useState(0)
useEffect(() => {
setTimeout(() => {
setNum(++num)
}, 2000)
}, [])
```
给提取到一个单独的组件中,这时候便是一个自定义hook,使得我们调用的代码更简洁,且逻辑抽离到了一起。
我们将上述代码抽离到`./hooks/numHook.js`中。
```react
import {useState, useEffect} from 'react'
export default function useNum() {
let [num, setNum] = useState(0)
useEffect(() => {
setTimeout(() => {
setNum(++num)
}, 2000)
}, [])
return [num, setNum]
}
```
这时候我们在需要引用该hook的地方进行导入引用即可,例子将可以改写为:
```react
import useNum from './hooks/numHook'
function Comp() {
let [num] = useNum()
return (
Comp -- {num}
)
}
function App() {
return (
);
}
export default App;
```
这就是最简单的自定义hook。
### 自定义请求数据hook
这里我们要做的自定义Hook是发起数据请求的hook
实现效果如下:

安装bootstrap:
```shell
npm i -S bootstrap
```
**server端**:
```js
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors())
app.get('/list', (req, res) => {
// 当前页和每页多少条
let {currentPage, perSize} = req.query
perSize = parseInt(perSize, 10)
// 数据 页数和条数对应得数据
let list = []
// 总数据条数
let total = 66
// 总页数
let pageCount = Math.ceil(total / perSize)
// 起始索引
let offset = (currentPage - 1) * perSize
if(currentPage >= pageCount) {
perSize = total % perSize
}
for(let i = offset; i < offset + perSize; i++) {
list.push({id: i+1, name: 'cai-'+(i+1)})
}
res.json({
currentPage,
perSize,
total,
pageCount,
list
})
})
app.listen(8080, () => {
console.log('listening on 8080...')
})
```
记得先启动服务端:
```node
node server
```
在`./hooks/useRequest.js`中:
```react
import {useState, useEffect} from 'react'
export default function useRequest() {
/* 用户可更改的请求数据 */
let [options, setOptions] = useState({currentPage: 1, pageSize: 10})
let [data, setData] = useState({
total: 0,
pageCount: 0,
list: []
})
// 请求数据
function reqeust() {
let {currentPage, pageSize} = options
fetch(`http://localhost:8080/list?currentPage=${currentPage}&perSize=${pageSize}`)
.then(res => res.json())
.then(res => setData({...res}))
}
useEffect(reqeust, [options])
return [data, options, setOptions]
}
```
这里的options state是单独抽离出来的,因为我们要返回给组件setOptions让他自定义请求参数(如:用户点击下一页时我们要重新改变请求参数的`currentPage`为当前页+1)。
```js
onClick={() => {
setOptions({ ...options, currentPage: index + 1 })
}}
```
组件一旦挂载我们就发起数据请求,然后将通过`setData`设置数据,并将`data`返回。可以看到最后返回的格式是[data, options, setOptions],意味着我们在组件内可以通过类似`useState`的方式获取自定义hook的值。
下面组件的取法:
```js
let [data, options, setOptions] = useRequest()
```
在`./pages/Tabel.js`中:
```react
import {useState} from 'react'
import useRequest from '../hooks/useRequest'
export default function Table() {
let [data, options, setOptions] = useRequest()
let { list, pageCount } = data
let [size, setSize] = useState(10)
return (
<>
| id |
name |
{list.map((item) => {
return (
| {item.id} |
{item.name} |
)
})}
{/* 下拉框 */}
>
)
}
```