繁体   English   中英

useSelector 和 useEffect 重新渲染优化

[英]useSelector and useEffect rerender optimization

我有 tableRows 存储在 useState 中的表组件。

我还有表组件之外的搜索器组件。

当 searcher 中的数据发生变化时,tableRows 会在 useEffect 中更新。

它工作得很好,但它会导致两次重新渲染。 我明白为什么。 第一次因为 useSelector 重新渲染,第二次因为 useEffect 有 useSelector 值作为依赖项。

但是如何避免一次重新渲染。 我希望它在 tableRows 更改时重新呈现,而不是在 searcher 更改时重新呈现。

 const CatalogTable: React.FC<CatalogTableProps> = ({rows}) => { const [tableRows, setTableRows] = React.useState(rows) const searcher = useSelector(getTableSearcher, shallowEqual) const getData = async () => { const {data} = await CatalogService.getAllCatalogProducts({page: 1, searcher: searcher}) setTableRows(data.products) } React.useEffect(() => { if(searcher) getData() }, [searcher]) return ( <> <div className={styles.defaultTable}> <Table headers={headers} label="Products catalog" rows={tableRows} total={total} pagination addButton editButtons searcher getPage={(page: number) => nextPage(page)} type='catalog' /> </div> </> ) } export default CatalogTable

一种可能的解决方案是记忆:

const CatalogTable: React.FC<CatalogTableProps> = ({rows}) => {
    const [tableRows, setTableRows] = React.useState(rows)
    const searcher = useSelector(getTableSearcher, shallowEqual)

    const getData = async () => {
        const {data} = await CatalogService.getAllCatalogProducts({page: 1, searcher: searcher})
        setTableRows(data.products)
    }


    React.useEffect(() => {
        if(searcher)
            getData()
    }, [searcher])

    const result = useMemo( () =>
        <>
            <div className={styles.defaultTable}>
                <Table
                    headers={headers}
                    label="Products catalog"
                    rows={tableRows}
                    total={total}
                    pagination
                    addButton
                    editButtons
                    searcher
                    getPage={(page: number) => nextPage(page)}
                    type='catalog'
                />
            </div>
        </>, [tableRows]
    );

  return result;
}

export default CatalogTable

另一种解决方案是将 tableRows 和搜索查询放在 redux 存储中,并通过异步中间件同时更新它们。

它重新渲染是因为您的 state 正在发生变化,这是预期的结果。 这是因为 tableRows 是在 useEffect 中设置的(效果里面有一个 setTableRows,这取决于搜索者)。

不确定组件的使用方式,因为您在道具中传递了一些初始行并重置组件内的行(setTableRows),但从您的评论看来,您并不真正关心搜索器中的更改。 完成您想要的解决方案是将行作为道具传递并从组件中删除 state,这样您的组件将只关心行而不关心搜索者。

无论如何,优化重新渲染并不是 go 的最佳方法,除非您的渲染速度很慢。 此外,在 useEffect 中定义异步调用更安全,这种方式更容易确保所有必需的依赖项都在依赖项数组中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM