Apakah cangkuk tindak balas?

青灯夜游
Lepaskan: 2022-04-08 18:49:52
asal
8029 orang telah melayarinya

Terdapat 10 cangkuk tindak balas: 1. useState, digunakan untuk menetapkan dan menukar keadaan; 2. useMemo, digunakan untuk mengawal keadaan kemas kini komponen; . useDebugValue, paparan sejak Tentukan label;

Apakah cangkuk tindak balas?

Persekitaran pengendalian tutorial ini: sistem Windows 7, bertindak balas versi 17.0.1, komputer Dell G3.

Apakah React Hook?

Tapak web rasmi React memperkenalkannya dengan cara ini: Hook ialah ciri baharu React 16.8. Ia membolehkan anda menggunakan keadaan dan ciri React lain tanpa menulis kelas.

  • Sepenuhnya pilihanAnda boleh mencuba Cangkuk dalam beberapa komponen tanpa menulis semula sebarang kod sedia ada. Tetapi anda tidak perlu belajar atau menggunakan Hooks sekarang jika anda tidak mahu.

  • 100% serasi ke belakang Cangkuk tidak mengandungi sebarang perubahan pecah.

  • Tersedia SekarangHook telah dikeluarkan dalam v16.8.0.

  • Tiada rancangan untuk mengalih keluar kelas daripada ReactAnda boleh membaca lebih lanjut mengenai strategi progresif untuk Hooks dalam bahagian di bahagian bawah halaman ini.

  • Hook tidak akan menjejaskan pemahaman anda tentang konsep React Sebaliknya, Hook menyediakan API yang lebih langsung untuk konsep React yang diketahui: props, state, context , refs dan kitaran hayat. Seperti yang akan kita lihat nanti, Hooks juga menyediakan cara yang lebih berkuasa untuk menggabungkannya.


Jika anda tidak cukup tahu tentang react, saya cadangkan anda membaca dokumentasi reaksi rasmi dahulu, tulis demo dan kemudian baca artikel itu, kerana saya hanya akan menyentuh beberapa perkara bertindak balas asas tanpa pergi ke butiran.
dokumentasi rasmi bertindak balas https://zh-hans.reactjs.org/docs/hooks-state.html

Cangkuk disediakan oleh React

hook 用途
useState 设置和改变state,代替原来的state和setState
useEffect 代替原来的生命周期,componentDidMount,componentDidUpdate 和 componentWillUnmount 的合并版
useLayoutEffect 与 useEffect 作用相同,但它会同步调用 effect
useMemo 控制组件更新条件,可根据状态变化控制方法执行、优化传值
useCallback useMemo优化传值,usecallback优化传的方法,是否更新
useRef 跟以前的ref,一样,只是更简洁了
useContext 上下文爷孙及更深组件传值
useReducer 代替原来redux里的reducer,配合useContext一起使用
useDebugValue 在 React 开发者工具中显示自定义 hook 的标签,调试使用。
useImperativeHandle 可以让你在使用 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>
  );
};
Salin selepas log masuk

Nota penggunaan ada dalam demo di atas
Selepas membaca penggunaan perbandingan useState di atas, a Struktur demo kecil adalah lebih jelas, kodnya lebih ringkas, dan ia lebih seperti menulis kod js.


2.useEffect & useLayoutEffect

useEffect menggantikan kitaran hayat asal, versi gabungan componentDidMount, componentDidUpdate dan componentWillUnmount
useEffect() > ;{ return ()=>{ } } , [ ])

  • Parameter pertama ialah fungsi Secara lalai, ia akan dicetuskan apabila memaparkan dan mengemas kini buat kali pertama dengan pulangan secara lalai. Fungsi menunjukkan bahawa ia boleh mengendalikan beberapa perkara sebelum ia boleh dimusnahkan
  • Parameter kedua, tatasusunan [], apabila kosong, ia bermakna ia hanya akan dilaksanakan sekali dan tidak akan dicetuskan apabila mengemas kini. Apakah parameter di dalam? Ia hanya akan dilaksanakan apabila parameter berubah Akan melaksanakan useEffect
    useEffect boleh digunakan beberapa kali, laksanakan dalam urutan
    useLayoutEffect<🎜. > untuk memaksa pelaksanaan useeffect menjadi segerak, dan laksanakan fungsi di dalam useLayoutEffect dahulu
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;
Salin selepas log masuk

3 useMemo & useCallback

Kedua-duanya boleh digunakan untuk mengoptimumkan isu pemaparan subkomponen atau mendengar perubahan keadaan subkomponen untuk mengendalikan acara Ini sukar dilakukan pada masa lalu, kerana shouldComponentUpdate boleh memantau sama ada ia telah berubah, tetapi tidak dapat mengawal luaran yang lain kaedah. Ia hanya boleh mengembalikan benar dan salah, dan componentDidUpdate hanya boleh dilaksanakan selepas mengemas kini, jadi saya mahu melakukannya sebelum membuat sesuatu.

useCallback belum tersedia lagi

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;
Salin selepas log masuk

4.useRef

ref hampir sama seperti sebelum ini, useRef dicipta – terikat – digunakan , tiga langkah Teruskan dan baca kod dan nota secara terperinci

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;
Salin selepas log masuk

5.useContext

Rakan yang pernah menggunakan konteks sebelum ini akan memahaminya di sepintas lalu. useContext adalah sama seperti penggunaan asas konteks adalah serupa. Terdapat ulasan terperinci dalam kod untuk menerangkan, mencipta, memindahkan nilai dan menggunakan

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;
Salin selepas log masuk

6.useReducer

Pengguna di sini akan Mengembalikan keadaan dan menghantar, menghantarnya kepada subkomponen melalui konteks, dan kemudian terus memanggil keadaan atau mencetuskan pengurangan Kami sering menggunakan useReducer dengan useContext createContext untuk mensimulasikan pemindahan nilai dan operasi penugasan semula 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;
Salin selepas log masuk
[Cadangan berkaitan:

Tutorial video Redis]

Atas ialah kandungan terperinci Apakah cangkuk tindak balas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan