寧波網(wǎng)絡(luò)推廣制作seo是哪里
1.?useImperativeHandle
- 在react中父組件可以通過forwardRef將ref轉(zhuǎn)發(fā)到子組件;
- 子組件拿到父組件創(chuàng)建的ref,綁定到自己的某個(gè)元素;
forwardRef的做法本身沒有什么問題,但是我們是將子組件的DOM直接暴露給了父組件,某下情況可能造成不可控的問題, 父組件可以拿到DOM后進(jìn)行任意的操作 。
通過 useImperativeHandle:
可以只暴露固定的操作, 通過useImperativeHandle的Hook,將傳入的ref和useImperativeHandle第二個(gè)參數(shù)返回的對(duì)象綁定到了一起,在父組件調(diào)用子組件的方法時(shí),通過自定義實(shí)現(xiàn),讓父組件使用返回的對(duì)象;
import React, { memo, useRef, forwardRef, useImperativeHandle } from 'react'const HelloWorld = memo(forwardRef((props, ref) => {const inputRef = useRef()// 子組件對(duì)父組件傳入的ref進(jìn)行處理useImperativeHandle(ref, () => {return {focus() {console.log("focus")inputRef.current.focus()},setValue(value) {inputRef.current.value = value}}})return <input type="text" ref={inputRef}/>
}))const App = memo(() => {const titleRef = useRef()const inputRef = useRef()function handleDOM() {// console.log(inputRef.current)inputRef.current.focus()// inputRef.current.value = ""inputRef.current.setValue("哈哈哈")}return (<div><h2 ref={titleRef}>哈哈哈</h2><HelloWorld ref={inputRef}/><button onClick={handleDOM}>DOM操作</button></div>)
})export default App
2.?useLayoutEffect
useLayoutEffect看起來和useEffect非常的相似,事實(shí)上他們也只有一點(diǎn)區(qū)別而已:
- useEffect會(huì)在渲染的內(nèi)容更新到DOM上后執(zhí)行,不會(huì)阻塞DOM的更新;
- useLayoutEffect會(huì)在渲染的內(nèi)容更新到DOM上之前執(zhí)行,會(huì)阻塞DOM的更新;
如果我們希望在某些操作發(fā)生之后再更新DOM,那么應(yīng)該將這個(gè)操作放到useLayoutEffect。
3. redux hooks
redux開發(fā)中,為了讓組件和redux結(jié)合起來,我們使用了react-redux中的connect:
- 這種方式必須使用高階函數(shù)結(jié)合返回的高階組件;
- 必須編寫:mapStateToProps和 mapDispatchToProps映射的函數(shù);
Redux7.1開始,提供了Hook的方式,我們?cè)僖膊恍枰帉慶onnect以及對(duì)應(yīng)的映射函數(shù)
useSelector的作用是將state映射到組件中:
- 參數(shù)一:將state映射到需要的數(shù)據(jù)中;
- 參數(shù)二:可以進(jìn)行比較來決定是否組件重新渲染(react-redux中提供了shallowEqual進(jìn)行比較);
useDispatch: 直接獲取dispatch函數(shù),之后在組件中直接使用即可;
import React, { memo } from 'react'
import { useSelector, useDispatch, shallowEqual } from "react-redux"
import { addNumberAction, changeMessageAction, subNumberAction } from './store/modules/counter'// memo高階組件包裹起來的組件有對(duì)應(yīng)的特點(diǎn): 只有props發(fā)生改變時(shí), 才會(huì)重新渲染
const Home = memo((props) => {const { message } = useSelector((state) => ({message: state.counter.message}), shallowEqual) // shallowEqual優(yōu)化,只有當(dāng)組件內(nèi)使用的state.message改變時(shí)重新加載 不會(huì)由于父組件更新了state的其他參數(shù)重新渲染const dispatch = useDispatch()function changeMessageHandle() {dispatch(changeMessageAction("你好啊, 師姐!"))}console.log("Home render")return (<div><h2>Home: {message}</h2><button onClick={e => changeMessageHandle()}>修改message</button></div>)
})const App = memo((props) => {// 1.使用useSelector將redux中store的數(shù)據(jù)映射到組件內(nèi)const { count } = useSelector((state) => ({count: state.counter.count}), shallowEqual)// 2.使用dispatch直接派發(fā)actionconst dispatch = useDispatch()function addNumberHandle(num, isAdd = true) {if (isAdd) {dispatch(addNumberAction(num))} else {dispatch(subNumberAction(num))}}console.log("App render")return (<div><h2>當(dāng)前計(jì)數(shù): {count}</h2><button onClick={e => addNumberHandle(1)}>+1</button><button onClick={e => addNumberHandle(6)}>+6</button><button onClick={e => addNumberHandle(6, false)}>-6</button><Home/></div>)
})export default App
4.?useTransition
返回一個(gè)狀態(tài)值表示過渡任務(wù)的等待狀態(tài),以及一個(gè)啟動(dòng)該過渡任務(wù)的函數(shù)。
打個(gè)比方:搜索過濾,在輸入框輸入時(shí),對(duì)于上w條數(shù)據(jù)時(shí),會(huì)存在卡頓,是由于在搜索的輸入事件中,event.target.value更新與過濾出來的數(shù)據(jù)同時(shí)更新,導(dǎo)致輸入存在卡頓原因。通過useTransition 在告訴react對(duì)于某部分任務(wù)的更新優(yōu)先級(jí)較低,可以稍后進(jìn)行更新。
useTransition返回兩個(gè)參數(shù)。
import React, { memo, useState, useTransition } from 'react'
import namesArray from './namesArray'const App = memo(() => {const [showNames, setShowNames] = useState(namesArray)const [ pending, startTransition ] = useTransition()function valueChangeHandle(event) {startTransition(() => {const keyword = event.target.valueconst filterShowNames = namesArray.filter(item => item.includes(keyword))setShowNames(filterShowNames)})}return (<div><input type="text" onInput={valueChangeHandle}/><h2>用戶名列表: {pending && <span>data loading</span>} </h2><ul>{showNames.map((item, index) => {return <li key={index}>{item}</li>})}</ul></div>)
})export default App