1. useMount
Следует настроить хук под названием useMount. Тогда функция обратного вызова будет выполняться только при первом рендеринге компонента.
Исходный код:
const useMount = (callback) => {
React.useEffect(callback, [])
}Пример:
const UseMountDemo = () => {
const [count, setCount] = React.useState(0)
useMount(() => {
console.log("useMount")
})
return (
<div>
count: { count }
<button onClick={() => setCount(count++)}>add</button>
</div>
)
}Когда компонент рендерится повторно, useMount не выполняется снова.
2. useUnmount
Можно разработать хук useUnmount, чтобы указать, что функция обратного вызова выполняется, когда компонент размонтирован.
Исходный код:
const useUnmount = (callback) => {
React.useEffect(() => {
return callback
}, [])
}Пример:
const Child = () => {
const [ count, setCount ] = useState(0)
useUnmount(() => {
// Мы ожидаем вывод значения num, когда компонент будет размонтирован
console.log('useUnmount', count)
})
return (
<div>
count: {count}
<button onClick={() => setCount(count + 1)}>add</button>
</div>
)
}
const UseUnmountedDemo = () => {
const [showChild, setShowChild] = React.useState(true);
// Мы используем "showChild" для управления отображением и скрытием дочернего компонента
return (
<div>
{ !!showChild && <Child /> }
<button onClick={() => setShowChild(false)}>Destroy child</button>
</div>
)
}
Когда компонент Child удаляется, функция обратного вызова useUnmount выполняется, но обнаруживается, что count — это начальное значение 0, а не 10. Что вызывает такой неправильный результат?Причина этого кроется в механизме закрытия в useEffect, потому что функция передается при выгрузке компонента для первого рендеринга. Чтобы получить состояние в реальном времени, нужно использовать useRef.
const useUnmount = (callback) => {
const callbackRef = React.useRef(callback)
callbackRef.current = callback
React.useEffect(() => {
return () => {
callbackRef.current()
}
}, [])
}Теперь при удалении компонента получаем правильное значение count
3. useContext
Иногда необходимо выполнять логический код только после изменения зависимости. Можно ли мы достичь этой цели, используя такой подход?
function UseUpdateEffectDemo() {
const [count, setCount] = React.useState(0)
React.useEffect(() => {
console.log('count changed', count)
}, [ count ])
return (
<div>
count: {count}
<button onClick={() => setCount(count + 1)}>change</button>
</div>
)
}Однако count выведет 0, как только компонент будет смонтирован. Как можно выполнить функцию обратного вызова после изменения count?
const useUpdateEffect = function (effectCallback, deps = []) {
const isFirstMount = React.useRef(false)
React.useEffect(() => {
return () => {
isFirstMount.current = false
}
}, [])
React.useEffect(() => {
// Не выполняйте effectcallback для первого раза
if (!isFirstMount.current) {
isFirstMount.current = true
} else {
return effectCallback()
}
}, deps)
}
function UseUpdateEffectDemo() {
const [count, setCount] = React.useState(0)
useUpdateEffect(() => {
console.log('Count changed', count)
}, [ count ])
return (
<div>
count: {count}
<button onClick={() => setCount(count + 1)}>change</button>
</div>
)
}4. useSetState
▪ Читать продолжение
@react_tg