redux 如何防止useSelector导致不必要的呈现?

kdfy810k  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(135)

我正在使用useSelector钩子来检索我的reducer的值,但是它在我的应用程序上造成了很多不必要的渲染。
我在组件上使用哪个属性并不重要,因为它们都从reducer获取相同的state对象,每次一个属性更改,所有使用useSelector的组件都会被渲染。
这是减速器:

const initialState = {
   productsDataState: [], // => this is populated by multiple objects
   searchProducts: [],
   isSearchOn: false,
   inputValue: '',
   listOrder: [],
   toastify: ['green', ''],
   toastifyOpen: false
}

const reducer = ((state = initialState, action) => {
   switch (action.type) {
      case actionTypes.UPDATE_PRODUCT:
         return {
            ...state,
            productsDataState: action.products,
            listOrder: action.listOrder
         }
      case actionTypes.SET_TOASTIFY:
         return {
            ...state,
            toastify: action.toastify,
            toastifyOpen: action.open
         }
      case actionTypes.SET_SEARCH:
         return {
            ...state,
            searchProducts: action.searchProducts,
            isSearchOn: action.isSearchOn,
            inputValue: action.inputValue
         }
      default:
         return state
   }
})

其中一个组件使用的是isSearchOn,它是一个布尔值,因此我解决了在渲染之前检查值是否为true的问题:

const { isSearchOn } = useSelector(state => state.isSearchOn && state)

但并不是所有组件都是这样的,我现在遇到的这个组件使用的是productsDataState属性,它是一个对象数组,在返回state之前,我不能只做一个简单的验证,我考虑过将初始值存储在一个useState中,在返回状态之前,对当前值和过去值做一个深入的比较,这与我在另一个组件中所做的工作类似,但我看不出这是一个好方法。

const { productsDataState } = useSelector(state => state)

是否有一种方法可以在不影响应用程序性能的情况下利用useSelector
我阅读了很多书,做了很多测试,但到目前为止,我还没有找到一个好的方法。
我想保留useSelector,但我愿意听取建议,即使它涉及到其他库。

55ooxyrt

55ooxyrt1#

您应该做的不是选择整个状态,而是选择您需要的部分:)

const productsDataState = useSelector(state => state.productsDataState)

@编辑
如果你想用一个选择器选择多个数据,你会导致它改变引用,例如,如果你试图使用一个对象。

const { productsDataState, other } = useSelector(state => ({ productsDataState: state.productsDataState, other: state.other }))

这将导致在任何状态更改时重新呈现,因为redux默认情况下使用严格相等性检查。
您应该听取官方文档并分别选择每个状态
Call useSelector() multiple times, with each call returning a single field value

相关问题