useSelect second parameter

时间:2021-05-22 作者:leemon

我使用useSelect 钩子在为块编辑器开发时从数据库中检索数据。

浏览古腾堡代码,我看到除了函数参数,useSelect 具有接受数组的可选第二个参数。

以下是一个示例:

const { media, mediaUpload } = useSelect(
    ( select ) => ( {
        media:
            id === undefined
                ? undefined
                : select( coreStore ).getMedia( id ),
        mediaUpload: select( blockEditorStore ).getSettings().mediaUpload,
    } ),
    [ id ]
);
有什么用[ id ] 在这个例子中?

在另一种情况下,传递一个空数组。以下是一个示例:

const { postId, isEditedPostNew, hasRemoteAutosave } = useSelect(
    ( select ) => ( {
        postId: select( \'core/editor\' ).getCurrentPostId(),
        isEditedPostNew: select( \'core/editor\' ).isEditedPostNew(),
        getEditedPostAttribute: select( \'core/editor\' )
            .getEditedPostAttribute,
        hasRemoteAutosave: !! select( \'core/editor\' ).getEditorSettings()
            .autosave,
    } ),
    []
);
有什么用[] 在这个例子中?

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

简短回答

的第二个参数useSelect 是的第二个参数useCallback, 因此,查看React网站,您就会了解第二个参数到底是什么……)

冗长的回答

useSelect 是一个使用核心的自定义反应挂钩useCallback 挂钩反应返回memoized 回调,可以避免对每个渲染进行昂贵的计算,如果useSelect 提供,则为documented: ()deps 是第二个参数,而mapSelect 是第一个参数)

depsArray: 如果提供,则会将mapSelect 所以是一样的mapSelect 在每次状态更改时调用,除非dependencieschange。

并通过;备忘录mapSelect"E;,这意味着useSelect 将呼叫useCallback 像这样:useCallback( mapSelect, deps ), 因此,第二个参数useSelect 实际上是的第二个参数useCallback, 以及:

如果deps 是空数组([]), mapSelect 将被记住,并且永远不会重新创建。

如果deps 是非空数组(例如。[ fooState ]), mapSelect 也将被记忆,但会重新创建only if 依赖关系(fooState) 已更改。

如果deps 不是数组,mapSelect 不会被记忆,因此它将始终被重新创建。

因此,这意味着,只要提供阵列mapSelect 将被记忆(或者您可以说它正在被缓存),以便在组件的下一个渲染和所有其他渲染中,使用相同的回调,而不是创建回调:

// Although these callbacks use the same code, they\'re not exactly the same.
const callback = ( a, b ) => a + b;
const callback2 = ( a, b ) => a + b;
console.log( callback === callback2 ); // false

// Same as above; these are not exactly the same.
const callback3 = function ( msg ) { alert( msg ); };
const callback4 = function ( msg ) { alert( msg ); };
console.log( callback3 === callback4 ); // false

// So because of that, the following callback will be created on the initial
// render and then recreated on the next renders.
const onClick = () => console.log( \'clicked\' );

// Therefore, if your callback is "heavy", then you can memoize your callback
// using the useCallback hook. And for example, the following callback will be
// created only on the initial render and then it\'s memoized so that on the
// next renders, the callback is not recreated and instead, the memoized one
// is used.
const onClick2 = useCallback( () => console.log( \'clicked\' ), [] );
PS:以上onClick 回调仅用于演示目的。在实际实现中,您不会希望记住这样的基本代码。。。因为在这种情况下,优化要比没有优化花费更多

关于空数组的注意事项([]) 与非空的比较(例如。[id])

So React表示:

依赖项数组不会作为参数传递给回调。不过,从概念上讲,它们就是这样表示的:回调中引用的每个值也应该出现在dependenciesarray中。

因此,在问题的第一个例子中,id 作为依赖项添加,因为它在回调中被引用,即。select( coreStore ).getMedia( id ), 如果id 不在dependencies数组中,则id 值始终为时间的初始值/当前值useSelect 调用,即在记忆回调之前。