最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Returning array of functions from custom react hook? - Stack Overflow

programmeradmin4浏览0评论

I have a custom react hook:

    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];
}

When using a hook like this in a component, the returned writeItem function changes every time the value changes (presumably because I create a new array every time).

How can I avoid re-renders of the Button component when I use my hook in an Item like so?

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

My current working but awkward approach is to return a useRef object instead of the array from my hook:

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;
}

Many thanks!

I have a custom react hook:

    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];
}

When using a hook like this in a component, the returned writeItem function changes every time the value changes (presumably because I create a new array every time).

How can I avoid re-renders of the Button component when I use my hook in an Item like so?

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

My current working but awkward approach is to return a useRef object instead of the array from my hook:

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;
}

Many thanks!

Share Improve this question asked May 5, 2020 at 15:44 Staffan_KStaffan_K 1331 gold badge1 silver badge6 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 21

You can make use of useCallback hook to memoize the functions so that they aren't created again on each render

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];
}
发布评论

评论列表(0)

  1. 暂无评论