自定义React-Hooks

一、React Hooks

1、Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性

二、Hooks 优点

1、可以抽离公共方法和逻辑,提高代码的可复用性

2、函数式组件更简洁,开发效率更高

三、自定义 Hook

1、通过自定义 Hook,可以将组件逻辑提取到可重用的函数中

2、自定义 Hook 是一个函数,其名称以 use 开头,函数内部可以调用其他的 Hook

自定义React-Hooks_第1张图片

3、初始化项目

create-react-app zhufeng_custom_hooks
cd zhufeng_custom_hooks
npm i express cors morgan bootstrap@3 react-router-dom --save

四、useRequest 

1、src\index.js

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css'
import {BrowserRouter,Route,Link} from 'react-router-dom';
import Table from './Table';
import Drag from './Drag';
import Form from './Form';
import Circle from './Circle';
ReactDOM.render(
  
  • Table
  • Drag
  • Form
  • Circle
, document.getElementById('root') );

2、src\Table.js

import React from 'react';
import useRequest from './hooks/useRequest';
const URL = 'http://localhost:8000/api/users';
export default function Table() {
    const [data, options,setOptions] = useRequest(URL);
    const { currentPage, totalPage, list } = data;
    return (
        <>
            
                    {
                        list.map(item => ())
                    }
                
ID姓名
{item.id}{item.name}
) }

3、src\hooks\useRequest.js

import { useState, useEffect } from 'react';
function useRequest(url) {
    let [options, setOptions] = useState({
        currentPage: 1,
        pageSize: 5
    });
    let [data, setData] = useState({
        totalPage: 0,
        list: []
    });
    function getData() {
        let { currentPage, pageSize } = options;
        fetch(`${url}?currentPage=${currentPage}&pageSize=${pageSize}`)
            .then(response => response.json())
            .then(result => {
                setData({...result});
            });
    }
    useEffect(getData, [options, url]);
    return [data,options, setOptions];
}

export default useRequest;

4、api.js

let express = require('express');
let cors = require('cors');
let logger = require('morgan');
let app = express();
app.use(logger('dev'));
app.use(cors());
app.get('/api/users', function (req, res) {
    let currentPage = parseInt(req.query.currentPage);
    let pageSize = parseInt(req.query.pageSize);
    let total=25;
    let list = [];
    let offset = (currentPage-1)*pageSize;
    for (let i = offset; i < offset + pageSize; i++) {
        list.push({ id: i + 1, name: 'name' + (i + 1) });
    }
    res.json({
        currentPage,
        pageSize,
        totalPage:Math.ceil(total/pageSize),
        list
    });
});
app.listen(8000,()=>{
    console.log('sever started at port 8000');

五、useDrag

自定义React-Hooks_第2张图片

1、基础

      1)触摸事件

事件名称 描述 是否包含 touches 数组
touchstart 触摸开始发
touchmove 滑动时接触点改变
touchend 手指离开屏幕时触摸结束

      2)触摸列表

参数 描述
touches 当前位于屏幕上的所有手指的列表
targetTouches 位于当前DOM元素上手指的列表

      3)Touch对象

参数 描述
clientX 触摸目标在视口中的x坐标
clientY 触摸目标在视口中的y坐标
pageX 触摸目标在页面中的x坐标
pageY 触摸目标在页面中的y坐标

2、实现

      1)src\index.js 

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css'
import Drag from './Drag';
ReactDOM.render(
  
{}
, document.getElementById('root') );

       2)src\Drag.js

import React from 'react';
import useDrag from './hooks/useDrag';
let style = {width:'100px',height:'100px',borderRadius:'50%'};
export default function Drag() {
    const [style1, dragRef1] = useDrag()
    const [style2, dragRef2] = useDrag()
    return (
        <>
            
) }

        3)src\hooks\useDrag.js

import { useLayoutEffect, useState, useRef } from 'react';
function useDrag() {
    const positionRef = useRef({
        currentX: 0, currentY: 0,
        lastX: 0, lastY: 0
    })
    const moveElement = useRef(null);
    const [, forceUpdate] = useState({});
    useLayoutEffect(() => {
        let startX, startY;
        const start = function (event) {
            const { clientX, clientY } =  event.targetTouches[0];
            startX = clientX;
            startY = clientY;
            moveElement.current.addEventListener('touchmove', move);
            moveElement.current.addEventListener('touchend', end);

        }
        const move = function (event) {
            const { clientX, clientY } = event.targetTouches[0];
            positionRef.current.currentX = positionRef.current.lastX + (clientX - startX);
            positionRef.current.currentY = positionRef.current.lastY + (clientY - startY);
            forceUpdate({});
        }
        const end = (event) => {
            positionRef.current.lastX = positionRef.current.currentX;
            positionRef.current.lastY = positionRef.current.currentY;
            moveElement.current.removeEventListener('touchmove', move);
                moveElement.current.removeEventListener('touchend', end);
        }
        moveElement.current.addEventListener('touchstart', start);

    }, []);
    return [{ x: positionRef.current.currentX, y: positionRef.current.currentY }, moveElement]
}

export default useDrag;

六、useForm

1、src\index.js

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css'
import Form from './Form';
ReactDOM.render(
  
{
}
, document.getElementById('root') );

2、src\Form.js

import React from 'react';
import useForm from './hooks/useForm';
export default function Form() {
    const [formData, setFormValue, resetFormValues] = useForm({username:'',email:''});
    return (
        
setFormValue('username', event.target.value)} />
setFormValue('email', event.target.value)} />
) }

3、useForm.js

import { useState } from 'react';
function useForm(values) {
    const [formData, setFormData] = useState(values);
    const setFormValue = (key, value) => {
        setFormData({...formData,[key]:value});
    }
    const resetFormValues = () => {
        setFormData(values);
    }
    return [formData, setFormValue, resetFormValues];
}

export default useForm;

七、useAnimation

1、src\index.js

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css'
import Circle from './Circle';
ReactDOM.render(
  
, document.getElementById('root') );

2、src\Circle.js

import useAnimation from './hooks/useAnimation';
import './Circle.css';
function Circle() {
  const [className, start] = useAnimation('circle','active');
    return (
      
); } export default Circle;;

3、src\Circle.css

.circle {
    width : 200px;
    height : 200px;
    background-color : gray;
    transition: all 2s;
}
.circle.active {
    background-color : green;
}

4、src\hooks\useAnimation.js

import {useState} from 'react';
function useAnimation(initialClassName,activeClassName) {
    const [className, setClassName] = useState(initialClassName);
    function start() {
        if (className === initialClassName) {
            setClassName(`${initialClassName} ${activeClassName}`);
        }else{
            setClassName(`${initialClassName}`);
        }
    }
    return [className, start];
}
export default useAnimation;

你可能感兴趣的:(react,react.js,javascript,前端)