Возврат массива функций из пользовательского хука реакции? - PullRequest
0 голосов
/ 05 мая 2020

У меня есть настраиваемый перехватчик реакции:

    function useItem(id) {

        const [value, setValue] = useState();

        useEffect(() => {
            databaseRead(id).then(i => setValue(i));
        }, [id]);

        function setItem(i) {
            setValue(i);
        }

        function writeItem(i) {
            databaseWrite(id, i);
        }

    return [value, setItem, writeItem];
}

При использовании такого перехватчика в компоненте возвращаемая функция writeItem изменяется каждый раз при изменении значения (предположительно, потому что я каждый раз создаю новый массив) .

Как я могу избежать повторного рендеринга компонента Button, когда я использую свой хук в Item, например?

function Item(props) {
    const [item, setItem, writeItem] = useItem(props.id);
    return(
        <>
            <ItemEditor data={item} setItem={setItem}/>
            <Button onPress={writeItem}/>
        </>
    )
}

Мой текущий рабочий, но неудобный подход - вернуть объект useRef вместо массива из моего хука:

function useItem(id) {
    const retVal = useRef({
       value: value, 
       setItem: setItem, 
       writeItem: writeItem
    }).current;

    const [dirty, setDirty] = useState();
    function makeDirty() { setDirty(Math.random()); }

    //and instead of setValue(i) do retVal.value=i; makeDirty();
    return retVal;
}

Большое спасибо!

1 Ответ

0 голосов
/ 05 мая 2020

Вы можете использовать хук useCallback, чтобы запоминать функции, чтобы они не создавались снова при каждом рендеринге

function useItem(id) {

        const [value, setValue] = useState();

        useEffect(() => {
            databaseRead(id).then(i => setValue(i));
        }, [id]);

        const setItem = useCallback(function(i) {
            setValue(i);
        }, []);

        const writeItem = useCallback(function(i) {
            databaseWrite(id, i);
        }, [id]) // this depends on id, and need to be recreated on id change

    return [value, setItem, writeItem];
}
...