Почему в React не добавили такой hook, и насколько хорошо он будет работать?
Я не силён в react и в его тестировании. И чтобы получше разобраться с React, я решил написать собственный hook, решающую популярную проблему с ререндерингом.
Проблема: к примеру, когда мы хотим привязать 2 дочерних компонента к одному родительскому состоянию (state из useState), то при изменении состояния происходит ререндер родительского компонента и как следствие всех дочерних компонентов. А в некоторых случаях хотелось бы чтобы происходил ререндер только тех компонентов, которые используют это состояние (state), исключая ререндер родительского компонента.
Для тех кому лень разбираться как работает мой hook (пара хуков), кратко опишу словами)
В родительском компоненте создаётся ref (из useRef). Дочерние компоненты подписываются на изменение этого ref и при изменении значения из ref происходит их принуждённый ререндер.
Стандартный useState
Синим подсвечены ререндеры
Мой hook
Код хука
import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react"
const MagicContext = createContext(null)
export const useMagic = (value) => {
const magicRef = useRef(value)
const rerenderFunctions = new Map()
const setMagicWithRerender = (value) => {
magicRef.current = value
const functions = Array.from(rerenderFunctions.values())
functions.forEach((foo) => {
foo()
})
}
const unsubscribe = (elem) => {
rerenderFunctions.delete(elem)
}
const subscribe = (elem, rerenderFoo) => {
rerenderFunctions.set(elem, rerenderFoo)
}
const MagicProvider = (props) => {
return <MagicContext.Provider value={{ magicRef, subscribe, unsubscribe, setMagicWithRerender }} {...props}>
</MagicContext.Provider>
}
return { MagicProvider }
}
export const useMagicContext = () => {
const { magicRef, subscribe, setMagicWithRerender, unsubscribe } = useContext(MagicContext)
const uniqRef = useRef(null)
const [rerender, setRerender] = useState(false)
useEffect(() => {
subscribe(uniqRef, () => {
setRerender((p) => !p)
})
return () => unsubscribe(uniqRef)
}, [unsubscribe, subscribe])
const magic = useMemo(() => {
return magicRef.current
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rerender])
return { setMagic: setMagicWithRerender, magic }
}
Вы можете попробовать hook здесь
Вопрос заключается в том, насколько правильно использовать такой функционал в react, насколько это правильно работает (и насколько он аналогичен стандартному связыванию через useState). Пожалуйста не оставляйте без ответа, хотя бы подскажите как я могу протестировать этот хук, или подскажите источники где я могу почитать про тестирование подобного.
И да, я понимаю что мой хук работает таким образом, что родительский компонент не имеет доступа к состоянию и не может его изменять!

