Maison > interface Web > Questions et réponses frontales > Que sont les crochets de réaction ?

Que sont les crochets de réaction ?

青灯夜游
Libérer: 2022-04-08 18:49:52
original
8105 Les gens l'ont consulté

Il existe 10 hooks de réaction : 1. useState, utilisé pour définir et modifier l'état ; 2. useMemo, utilisé pour contrôler les conditions de mise à jour des composants ; 3. useContext, utilisé pour transférer des valeurs aux composants ; étiquettes personnalisées ; 5 , useCallback et ainsi de suite.

Que sont les crochets de réaction ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, React version 17.0.1, ordinateur Dell G3.

Qu’est-ce que React Hook ?

Le site officiel de React le présente ainsi : Hook est une nouvelle fonctionnalité de React 16.8. Il vous permet d'utiliser l'état et d'autres fonctionnalités de React sans écrire de classes.

  • Complètement facultatifVous pouvez essayer des Hooks dans certains composants sans réécrire le code existant. Mais vous n’êtes pas obligé d’apprendre ou d’utiliser Hooks pour le moment si vous ne le souhaitez pas.

  • 100% rétrocompatible Hook ne contient aucune modification radicale.

  • Disponible maintenant Hook est sorti en v16.8.0.

  • Il n'est pas prévu de supprimer des classes de ReactVous pouvez en savoir plus sur la stratégie progressive pour Hooks dans la section au bas de cette page.

  • Hook n'affectera pas votre compréhension des concepts ReactAu contraire, Hook fournit une API plus directe pour les concepts React connus : accessoires, état, contexte, références et cycle de vie. Comme nous le verrons plus tard, les Hooks offrent également un moyen plus puissant de les combiner.


Si vous n'en savez pas assez sur React, il est recommandé de lire d'abord la documentation officielle de React, d'écrire une démo puis de lire l'article, car j'aborderai brièvement quelques éléments de base sur React sans entrer dans les détails. .
documentation officielle de React https://zh-hans.reactjs.org/docs/hooks-state.html

Hook fourni par React

hook Usage
useState paramètres et modifications state, remplaçant l'état d'origine et setState
useEffect remplaçant le cycle de vie d'origine, la version fusionnée de composantDidMount, composantDidUpdate et composantWillUnmount
useLayoutEffect a le même effet que useEffect, mais elle appellera l'effet de manière synchrone
useMemo Contrôlez les conditions de mise à jour des composants, qui peuvent contrôler l'exécution de la méthode et optimiser le transfert de valeur en fonction des changements d'état
useCallback useMemo optimise le transfert de valeur, usecallback optimise la méthode de transfert, s'il faut mettre à jour
useRef Identique à la référence précédente, la même, juste plus concise
useContext Le contexte et les composants plus profonds transmettent la valeur
useReducer remplace le réducteur dans le redux d'origine et est utilisé avec useContext
useDebugValue dans React L'étiquette du hook personnalisé est affichée dans les outils de développement pour le débogage.
useImperativeHandle vous permet de personnaliser la valeur d'instance exposée au composant parent lors de l'utilisation de ref.

1.useState

import React from 'react';
import './App.css';
//通常的class写法,改变状态
class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      hook:'react hook 是真的好用啊'
    }
  }
  changehook = () => {
    this.setState({
      hook:'我改变了react hook 的值'
    })
  }
  render () {
    const { hook } = this.state
    return(
         <header className="App-header">
          {hook}
          <button onClick={this.changehook}>
            改变hook
          </button>
        </header>
      )
  }
}
export  {App}

//函数式写法,改变状态
function App() {
//创建了一个叫hook的变量,sethook方法可以改变这个变量,初始值为‘react hook 是真的好用啊’
 const [hook, sethook] = useState("react hook 是真的好用啊");
  return ( 
    <header className="App-header">
      {hook}{/**这里的变量和方法也是可以直接使用的 */}
      <button onClick={() => sethook("我改变了react hook 的值")}>
        改变hook
      </button>
    </header>
  );
}
export  {App}

//箭头函数的函数写法,改变状态
export const App = props => {
  const [hook, sethook] = useState("react hook 是真的好用啊");
  return (
    <header className="App-header">
      {hook}
      <button onClick={() => sethook("我改变了react hook 的值")}>
        改变hook
      </button>
    </header>
  );
};
Copier après la connexion

Les notes d'utilisation sont dans la démo ci-dessus
Après avoir lu l'utilisation comparative de useState ci-dessus, une petite démo a une structure plus claire et un code plus simple, plus comme écrire du code js et l'appliquer au projet In, ne serait-ce pas merveilleux ?


2.useEffect & useLayoutEffect

useEffect remplace le cycle de vie d'origine, la version fusionnée de composantDidMount, composantDidUpdate et composantWillUnmount
useEffect( ()=>{ return ()=>{ } } , [ ])

  • Le premier paramètre est une fonction. Par défaut, il sera déclenché lors du rendu et de la première mise à jour. Il est livré avec un retour par défaut. Renvoyer une fonction signifie que certaines choses peuvent être traitées avant d'être détruites. Le deuxième paramètre est un tableau []. Lorsqu'il est vide, cela signifie qu'il ne sera exécuté qu'une seule fois et ne sera pas déclenché lors de la mise à jour. Quels sont les paramètres à l'intérieur qui seront exécutés lorsque les paramètres changent et peuvent être utilisés plusieurs fois. exécuté dans l'ordre. UseLayoutEffect est forcé d'être exécuté de manière synchrone et exécutez d'abord la fonction dans useLayoutEffect
  • import React, { useState, useEffect, useLayoutEffect } from &#39;react&#39;;
    
    //箭头函数的写法,改变状态
    const UseEffect = (props) => {
    	//创建了一个叫hook的变量,sethook方法可以改变这个变量,初始值为‘react hook 是真的好用啊’
    	const [ hook, sethook ] = useState(&#39;react hook 是真的好用啊&#39;);
    	const [ name ] = useState(&#39;baby张&#39;);
    	return (
    		<header className="UseEffect-header">
    			<h3>UseEffect</h3>
    			<Child hook={hook} name={name} />
    			{/**上面的变量和下面方法也是可以直接使用的 */}
    			<button onClick={() => sethook(&#39;我改变了react hook 的值&#39; + new Date().getTime())}>改变hook</button>
    		</header>
    	);
    };
    
    const Child = (props) => {
    	const [ newhook, setnewhook ] = useState(props.hook);
    	//这样写可以代替以前的componentDidMount,第二个参数为空数组,表示该useEffect只执行一次
    	useEffect(() => {
    		console.log(&#39;first componentDidMount&#39;);
    	}, []);
    
    	//第二个参数,数组里是hook,当hook变化时,useEffect会触发,当hook变化时,先销毁再执行第一个函数。
    	useEffect(
    		() => {
    			setnewhook(props.hook + &#39;222222222&#39;);
    			console.log(&#39;useEffect&#39;);
    			return () => {
    				console.log(&#39;componentWillUnmount &#39;);
    			};
    		},
    		[ props.hook ]
    	);
    
    	//useLayoutEffect 强制useeffect的执行为同步,并且先执行useLayoutEffect内部的函数
    	useLayoutEffect(
    		() => {
    			console.log(&#39;useLayoutEffect&#39;);
    			return () => {
    				console.log(&#39;useLayoutEffect componentWillUnmount&#39;);
    			};
    		},
    		[ props.hook ]
    	);
    
    	return (
    		<div>
    			<p>{props.name}</p>
    			{newhook}
    		</div>
    	);
    };
    
    export default UseEffect;
    Copier après la connexion

    3 useMemo & useCallback
    Ils peuvent tous deux être utilisés pour optimiser le problème de rendu des sous-composants, ou. écouter les changements d'état des sous-composants pour gérer les événements, ce qui était très courant dans le passé. C'est difficile à faire car ShouldComponentUpdate peut surveiller s'il y a des changements, mais ne peut pas contrôler d'autres méthodes externes. Il ne peut renvoyer que vrai et faux, et composantDidUpdate le peut. ne doit être exécuté qu'après la mise à jour, il n'est donc pas bon de faire quelque chose avant le rendu.
  • useCallback n'est pas encore disponible
import React, { useState, useMemo } from &#39;react&#39;;

const Child = ({ age, name, children }) => {
    //在不用useMemo做处理的时候,只要父组件状态改变了,子组件都会渲染一次,用了useMemo可以监听某个状态name,当name变化时候执行useMemo里第一个函数
    console.log(age, name, children, &#39;11111111&#39;);
	function namechange() {
		console.log(age, name, children, &#39;22222222&#39;);
		return name + &#39;change&#39;;
    }
     {/** react 官网虽说useCallback与useMemo的功能差不多,但不知道版本问题还怎么回是,这个方法目前还不能用
    const memoizedCallback = useCallback(
        () => {
            console.log(&#39;useCallback&#39;)
        },
        [name],
      );
    console.log(memoizedCallback,&#39;memoizedCallback&#39;)
     */}
    //useMemo有两个参数,和useEffect一样,第一个参数是函数,第二个参数是个数组,用来监听某个状态不变化
	const changedname = useMemo(() => namechange(), [ name ]);
	return (
		<div style={{ border: &#39;1px solid&#39; }}>
			<p>children:{children}</p>
			<p>name:{name}</p>
			<p>changed:{changedname}</p>
			<p>age:{age}</p>
		</div>
	);
};

const UseMemo = () => {
    //useState 设置名字和年龄,并用2两个按钮改变他们,传给Child组件
	const [ name, setname ] = useState(&#39;baby张&#39;); 
	const [ age, setage ] = useState(18);
	return (
		<div>
			<button
				onClick={() => {
					setname(&#39;baby张&#39; + new Date().getTime()); 
				}}
			>
				改名字
			</button>
			<button
				onClick={() => {
					setage(&#39;年龄&#39; + new Date().getTime());
				}}
			>
				改年龄
			</button>
			<p>
				UseMemo {name}:{age}
			</p>
			<Child age={age} name={name}>
				{name}的children
			</Child>
		</div>
	);
};

export default UseMemo;
Copier après la connexion

4.useRef

ref est presque le même qu'avant, création useRef – liaison – utilisation, trois étapes, veuillez lire le code et les notes en détail

import React, { useState, useRef } from &#39;react&#39;;

const UseRef = () => {
	//这里useState绑定个input,关联一个状态name
	const [ name, setname ] = useState(&#39;baby张&#39;);
	const refvalue = useRef(null);// 先创建一个空的useRef
	function addRef() {
		refvalue.current.value = name;   //点击按钮时候给这个ref赋值
		// refvalue.current = name  //这样写时,即使ref没有绑定在dom上,值依然会存在创建的ref上,并且可以使用它
		console.log(refvalue.current.value);
	}
	return (
		<div>
            <input
                defaultValue={name}
				onChange={(e) => {
					setname(e.target.value);
                }}
			/>
			<button onClick={addRef}>给下面插入名字</button>
			<p>给我个UseRef名字:</p>
			<input ref={refvalue} />
		</div>
	);
};

export default UseRef;
Copier après la connexion


5. useContext

Les amis qui ont déjà utilisé le contexte le comprendront en un coup d'œil. L'utilisation de base de useContext est similaire au contexte précédent. Il y a des commentaires détaillés dans le code, la création, le transfert de valeur, l'utilisation

import React, { useState, useContext, createContext } from &#39;react&#39;;

const ContextName = createContext();
//这里为了方便写博客,爷爷孙子组件都写在一个文件里,正常需要在爷爷组件和孙子组件挨个引入创建的Context

const UseContext = () => {
	//这里useState创建一个状态,并按钮控制变化
	const [ name, setname ] = useState(&#39;baby张&#39;);
	return (
		<div>
			<h3>UseContext 爷爷</h3>
			<button
				onClick={() => {
					setname(&#39;baby张&#39; + new Date().getTime());
				}}
			>
				改变名字
			</button>
			{/**这里跟context用法一样,需要provider向子组件传递value值,value不一定是一个参数 */}}
			<ContextName.Provider value={{ name: name, age: 18 }}>
				{/**需要用到变量的子组件一定要写在provider中间,才能实现共享 */}
				<Child />
			</ContextName.Provider>
		</div>
	);
};

const Child = () => {
	//创建一个儿子组件,里面引入孙子组件
	return (
		<div style={{ border: &#39;1px solid&#39; }}>
			Child 儿子
			<ChildChild />
		</div>
	);
};

const ChildChild = () => {
	//创建孙子组件,接受爷爷组件的状态,用useContext,获取到爷爷组件创建的ContextName的value值
	let childname = useContext(ContextName);
	return (
		<div style={{ border: &#39;1px solid&#39; }}>
			ChildChild 孙子
			<p>
				{childname.name}:{childname.age}
			</p>
		</div>
	);
};

export default UseContext;
Copier après la connexion


6. useReducer

Le usereducer ici connaîtra l'état de retour et la répartition, les transmettra au sous-composant via le contexte, puis appellera directement l'état ou déclenchera le réducteur. Nous utilisons souvent useReducer avec useContext createContext pour simuler les opérations de transfert de valeur et de réaffectation. de reudx.

import React, { useState, useReducer, useContext, createContext } from &#39;react&#39;;

//初始化stroe的类型、初始化值、创建reducer
const ADD_COUNTER = &#39;ADD_COUNTER&#39;;
const initReducer = {
	count: 0
};
//正常的reducer编写
function reducer(state, action) {
	switch (action.type) {
		case ADD_COUNTER:
			return { ...state, count: state.count + 1 };
		default:
			return state;
	}
}

const CountContext = createContext();
//上面这一段,初始化state和reducer创建context,可以单独写一个文件,这里为了方便理解,放一个文件里写了

const UseReducer = () => {
	const [ name, setname ] = useState(&#39;baby张&#39;);
	//父组件里使用useReducer,第一个参数是reducer函数,第二个参数是state,返回的是state和dispash
	const [ state, dispatch ] = useReducer(reducer, initReducer);
	return (
		<div>
			UseReducer
			{/* 在这里通过context,讲reducer和state传递给子组件*/}
			<CountContext.Provider value={{ state, dispatch, name, setname }}>
				<Child />
			</CountContext.Provider>
		</div>
	);
};

const Child = () => {
	//跟正常的接受context一样,接受父组件的值,通过事件等方式触发reducer,实现redux效果
	const { state, dispatch, name, setname } = useContext(CountContext);
	function handleclick(count) {
		dispatch({ type: ADD_COUNTER, count: 17 });
		setname(count % 2 == 0 ? &#39;babybrother&#39; : &#39;baby张&#39;);
	}
	return (
		<div>
			<p>
				{name}今年{state.count}岁
			</p>
			<button onClick={() => handleclick(state.count)}>长大了</button>
		</div>
	);
};

export default UseReducer;
Copier après la connexion
【Recommandations associées :
Tutoriel vidéo Redis

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal