为什么useDispatch重新渲染父组件?

时间:2020-03-03 21:25:08

标签: javascript reactjs redux react-hooks

我正在Tree组件(来自Ant库)的onSelect回调中使用useDispatch钩子(来自Redux):

export const MyComponent = () => {

    const dispatch = useDispatch();

    const onSelect = (selectedNode) => {
            const selectedItem = selectedNode[0];
            dispatch(fetchSelectedItems(selectedItem));
    };

    return 
        <Tree
            onSelect={onSelect}
        >
            <TreeNode .. />
            <TreeNode .. />
            <TreeNode .. />
        </Tree
}


export const fetchSelectedItems = (selected: string) =>
    (dispatch) =>
        axios({
            url: `/api/items?id=${selected}`,
            method: 'GET',
        }).then(response => {
            dispatch(fetchSelectedItemsSuccess(response.data))
        }).catch((error: any) => {throw(error)});

为什么useDispatch重新渲染父组件?有什么办法可以防止这种情况?我尝试过useCallback就像Redux文档中的一样,但是this solution是为了防止子组件而不是父项重新呈现。

3 个答案:

答案 0 :(得分:1)

看来我在the comment中的假设是正确的。

所以我将向您显示解决方法。
您可以将容器中使用var labels = new List<Label> { label1, label2, label3}; var textBoxs = new List<TextBox> { text1, text2, text3}; for (int i = 1; i <= 5; i++) { try { tcpCLient.ConnectAsync(textBoxs[i].Text, 80); labels[i].Text = "Online"; } catch (Exception) { labels[i].Text = "Offline"; } } 的零件提取到另一个组件,例如clickValue

这样做只会隔离对ClickValue组件的更新。

我的叉子:https://codesandbox.io/s/soanswer60515755-9cc7u

ClickValue

在下面查看配置文件结果。

profile result

答案 1 :(得分:0)

我认为在每个渲染上都需要重新声明onSelect函数。函数是引用类型。在每次渲染时传递带有新引用的已重新声明的函数将导致重新渲染。也许您应该研究使用上下文。

答案 2 :(得分:0)

我重新渲染组件的问题是由父组件(我直接引用useSelector)中使用的state引起的。很有可能是因为此选择器的新结果。

解决方案: 我用reselect library重写了这些选择器以使其记忆化(在此处的注释之一中建议这样做,但我不知道为什么将其删除了)。我所做的正是关于memoized selectors的redux文档中的内容。