This is the 15th day of my participation in Gwen Challenge

Hooks Introduction and application scenarios

Hooks are a new feature since 16.8, and the React team wants components not to become complex containers, but rather pipes for data flow. Developers can assemble pipes as needed. Components are best written as functions, not classes. React has long supported function components. Here’s an example.

 function Welcome(props) {
        return <h1> Hello ,{props.name}</h1>
    }
Copy the code

However, this approach has significant limitations. It must be pure functions, cannot contain states, and does not support lifecycle methods, so it cannot replace classes.

React Hooks are designed to write fully functional components without using classes at all.

Hooks enable stateless components to implement some of the functions of stateful components, such as setting state, using hook functions: componentDidMount, componentDidUpdate, componentWillUnmount.

UseState in hooks

Deconstruct properties and set property methods from useState

import React,{useState, useEffect} from 'react'

export default function Hooks() {
    const [title,setTile] = useState('home')

    function changeTitle() {
        setTile('change the title')}}Copy the code

UseEffect method in hooks

UseEffect retrieves changed properties

 UseEffect if the value is the same, it will not be executed
    useEffect(() = > {
            return () = > {
                The cb method in return is equivalent to componentWillUnmount
                document.title = title
                console.log('componentWillUnmount... ')
            }
        },
        [title]
    )
Copy the code

example

import React,{useState,useEffect} from 'react';
import Css from "./assets/css/app.css";

// Use stateless components
function App() {
    const [title, setTitle] = useState('home') // useState destructs properties and sets properties

    function changeTitle() {
        setTitle('hooks')}UseEffect if the value is the same, it will not be executed
    useEffect(() = > {
            return () = > {
                The cb method in return is equivalent to componentWillUnmount
                document.title = title
                console.log('componentWillUnmount... ')
            }
        },
        [title]
    )

    return (
        <div className={Css['app']} >
            <div>{title}</div>
            <button onClick={changeTitle.bind(this)}>Change the title</button>
        </div>)}export default App;

Copy the code

The effect

Four, useReducer

React itself does not provide state management, and external libraries are usually required. The most commonly used library for this is Redux.

The core concept of Redux is that components emit actions to communicate with the state manager. After the state manager receives the action, the Reducer function is used to calculate the newState. The Reducer function is in the form of (state, action) = newState

Example: Create a new JS that handles the useReducer method

export let defaultState = {count: 0}

export let countReducer = (state =defaultState,action) = >
                         {
                             switch (action.type) {
                                 case 'inc': / / addstate = {... state, ... action.payload}break;
                                 case 'dec': / / reducestate = {... state, ... action.payload}break;
                             }
                             return state
                         }
Copy the code

Then use useReducer in app.js

import React,{useReducer} from 'react';
import Css from "./assets/css/app.css";
import {defaultState,countReducer} from './hooksReducer/reducerCount'
let iCount = 0
function App() {
    let thing = useReducer(countReducer,defaultState)
    let [state,dispatch] = thing
    return (
        <div className={Css['app']} >Calculation:<button onClick={()= > dispatch({type: 'dec', payload: {count: --iCount}})}>-</button>
                    {state.count}
                <button onClick={()= > dispatch({type: 'inc', payload: {count: ++iCount}})}>+</button>
        </div>)}export default App;

Copy the code

The effect

Five useContext.

Equivalent to the BUS in Vue communicating in the component

5.1 Creating a Context. js file

import React from 'react'

export default React.createContext()
Copy the code

5.2 Encapsulating count Components

This is the consumer

import React,{useContext} from 'react';
import Context from '.. /.. /context'
function Count() {
    let countContext = useContext(Context)
    return (
        <div>Sub-component calculation:<button onClick={()= > countContext.dispatch({type: 'dec', payload: {count: --countContext.state.count}})}>-</button>
            {countContext.state.count}
            <button onClick={()= > countContext.dispatch({type: 'inc', payload: {count: ++countContext.state.count}})}>+</button>
        </div>)}export default Count;

Copy the code

5.3 Using Context.js in app.js

This is the information provider

import React,{useReducer} from 'react';
import Css from "./assets/css/app.css";
import {defaultState,countReducer} from './hooksReducer/reducerCount'
import Context from './context'
import  Count from './component/count'
let iCount = 0
function App() {
    let thing = useReducer(countReducer,defaultState)
    let [state,dispatch] = thing
    return (
        <div className={Css['app']} >
            <Context.Provider value={{state,dispatch}}>
                <Count></Count>Calculation:<button onClick={()= > dispatch({type: 'dec', payload: {count: --iCount}})}>-</button>
                    {state.count}
                <button onClick={()= > dispatch({type: 'inc', payload: {count: ++iCount}})}>+</button>
            </Context.Provider>
        </div>)}export default App;

Copy the code

The effect

X: hooks

6.1 app. Js

import React from 'react';
import Swiper from './components/swiper';
import Css from "./assets/css/app.css";
class App extends React.Component{
    constructor(){
        super(a);this.state={
            images: [].images2:[]
        };
    }
    componentDidMount(){
        setTimeout(() = >{
            let images=[
                {src:require("./assets/images/banner1.jpg"),url:"Https://pages.tmall.com/wow/a/act/tmall/tmc/23759/wupr?spm=875.7931836/B.2016006.d6.66144265aPX4zF&trackInfo=2016081510 0101; 64866506034; 287638; 587431337429; 3; 287638 _587431337429; 1007.14152.68669.100200300000000; 92ba02ea-a2a8-4bbe-99ac-d5c3abf2eba5; 3; 0; 10000002&item_id=587431337429&pvid=92ba02ea-a2a8-4bbe-99ac-d5c3abf2eba5&pos=3&activity_id=287638&wh_pid=industry-170400& Acm = 07055.1003.1.2519102 & SCM = 1003.1.20160815. OTHER_0_6801489"},
                {src:require("./assets/images/banner2.jpg"),url:"Https://pages.tmall.com/wow/a/act/tmall/tmc/23759/wupr?spm=875.7931836/B.2016006.d1.66144265aPX4zF&trackInfo=2016081510 0101; 64950842484; 288994; 530549532317; 3; 288994 _530549532317; 1007.14152.68669.100200300000000; 92ba02ea-a2a8-4bbe-99ac-d5c3abf2eba5; 1; 0; 10000002&item_id=530549532317&pvid=92ba02ea-a2a8-4bbe-99ac-d5c3abf2eba5&pos=1&activity_id=288994&wh_pid=industry-170636& Acm = 07055.1003.1.2519102 & SCM = 1003.1.20160815. OTHER_0_6810849"},
                {src:require("./assets/images/banner3.jpg"),url:"Https://www.tmall.com/wow/brand/act/fashion?acm=lb-zebra-2386-265936.1003.4.410386&scm=1003.4.lb-zebra-2386-265936.OTHE R_1_410386 & ali_trackid = 19 _4803ba43894904cab9c8c08820f2e4a5 & SPM = 875.7931836 / b. 2016006. D2. ""}];this.setState({images:images});
            let images2=[
                {src:require("./assets/images/banner2.jpg"),url:"Https://pages.tmall.com/wow/a/act/tmall/tmc/23759/wupr?spm=875.7931836/B.2016006.d6.66144265aPX4zF&trackInfo=2016081510 0101; 64866506034; 287638; 587431337429; 3; 287638 _587431337429; 1007.14152.68669.100200300000000; 92ba02ea-a2a8-4bbe-99ac-d5c3abf2eba5; 3; 0; 10000002&item_id=587431337429&pvid=92ba02ea-a2a8-4bbe-99ac-d5c3abf2eba5&pos=3&activity_id=287638&wh_pid=industry-170400& Acm = 07055.1003.1.2519102 & SCM = 1003.1.20160815. OTHER_0_6801489"},
                {src:require("./assets/images/banner3.jpg"),url:"Https://pages.tmall.com/wow/a/act/tmall/tmc/23759/wupr?spm=875.7931836/B.2016006.d1.66144265aPX4zF&trackInfo=2016081510 0101; 64950842484; 288994; 530549532317; 3; 288994 _530549532317; 1007.14152.68669.100200300000000; 92ba02ea-a2a8-4bbe-99ac-d5c3abf2eba5; 1; 0; 10000002&item_id=530549532317&pvid=92ba02ea-a2a8-4bbe-99ac-d5c3abf2eba5&pos=1&activity_id=288994&wh_pid=industry-170636& Acm = 07055.1003.1.2519102 & SCM = 1003.1.20160815. OTHER_0_6810849"},
                {src:require("./assets/images/banner1.jpg"),url:"Https://www.tmall.com/wow/brand/act/fashion?acm=lb-zebra-2386-265936.1003.4.410386&scm=1003.4.lb-zebra-2386-265936.OTHE R_1_410386 & ali_trackid = 19 _4803ba43894904cab9c8c08820f2e4a5 & SPM = 875.7931836 / b. 2016006. D2. ""}];this.setState({images2:images2})
        },400)}render(){
        return (
            <div className={Css["app"]} >
                <div class={Css["banner"]} >
                    <Swiper data={this.state.images}></Swiper>
                </div>
                <div className={Css["banner"]} >
                    <Swiper data={this.state.images2}></Swiper>
                </div>
            </div>)}}export default App;

Copy the code

6.2 Encapsulated Swiper Hooks components

index.js

import React from 'react';
import Hoc from './hoc';
import "./style.css";
export default Hoc((props) = >{
    return(
        <div className="my-swiper-main" onMouseOver={props.stop} onMouseOut={props.autoPlay}>
            {
                (props.data && props.data.length>0) && props.data.map((item,index)=>{
                    return (
                        <div className={item.active?"slide show":"slide"} key={index}>
                            <a href={item.url} target="_blank" rel="noopener noreferrer"><img src={item.src} alt=""/></a>
                        </div>)})}<div className="pagination">
                {
                    (props.data && props.data.length>0) && props.data.map((item,index)=>{
                        return (
                            <div className={item.active?"dot active":"dot"} key={index} onClick={()= >{props.changeImg(index)}}></div>)})}</div>
        </div>)})Copy the code

6.3 hoc. Js

import React,{useEffect,useState,useRef,useCallback} from 'react';
import PropTypes from 'prop-types';
export default function Hoc(WithComponent){
    function HocComponent(props){
        let [data,setData]=useState([]);
        let [isInit,setIsInit]=useState(true);
        let [iIndex,setIndex]=useState(0);
        // Create a generic representation of the container
        let timer=useRef(null);
        // Click to switch images
        function changeImg(index){
            setIndex(index);
            if(data && data.length>0) {for(let i=0; i<data.length; i++){if(data[i].active){
                        data[i].active=false;
                        break;
                    }
                }
                data[index].active=true; setData(data); }}// Auto play
        const autoPlay=useCallback(() = >{
            clearInterval(timer.current);
            timer.current=setInterval(() = >{
                let tmpIndex=iIndex;
                if(data && data.length>0) {for(let i=0; i<data.length; i++){if(data[i].active){
                            data[i].active=false;
                            break; }}if(tmpIndex>=data.length-1){
                        tmpIndex=0;
                    }else {
                        tmpIndex++;
                    }
                    data[tmpIndex].active=true; setIndex(tmpIndex); setData(data); }},3000)
        },[data,iIndex]);
        // Stop auto play
        function stop(){
            clearInterval(timer.current);
        }
        useEffect(() = >{
            if(props.data && props.data.length>0 && isInit){
                setIsInit(false);
                for(let i=0; i<props.data.length; i++){if(i===0){
                        props.data[i].active=true;
                    }else{
                        props.data[i].active=false;
                    }
                }
                setData(props.data);
            }
            autoPlay();
            // execute when the page leaves
            return () = >{
                clearInterval(timer.current);
            }
        },[props.data,isInit,autoPlay]);
        let newsProps={
            changeImg,
            data,
            stop,
            autoPlay
        };
        return (
            <WithComponent {. props} {. newsProps} ></WithComponent>
        )
    }
    HocComponent.propTypes={
        data:PropTypes.array.isRequired
    };
    return HocComponent;
}
Copy the code

The effect