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