Почему в 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). Пожалуйста не оставляйте без ответа, хотя бы подскажите как я могу протестировать этот хук, или подскажите источники где я могу почитать про тестирование подобного.

И да, я понимаю что мой хук работает таким образом, что родительский компонент не имеет доступа к состоянию и не может его изменять!


Ответы (0 шт):