我试图理解处理大量子组件时的开销,使用reducer从状态中提取数据。
考虑到这三种不同的方法,哪一种是最有效的?我的直觉告诉我选择二。但我说得对吗而且,在它被编译之后,它会有那么大的不同吗?
选项一
// call the reducer once, and pass all data
const MainComponent = () => {
const { data } = useMyReducer()
return (
<SubComponent id="one" data={data} />
<SubComponent id="two" data={data} />
<SubComponent id="three" data={data} />
<SubComponent id="four" data={data} />
// and many more
)
}
const SubComponent = ({id, data}) => {
const myData = data[id]
return (
<div>{myData}</div>
)
}
选项二
// call the reducer once, and pass required data only
const MainComponent = () => {
const { data } = useMyReducer()
return (
<SubComponent id="one" data={data.one} />
<SubComponent id="two" data={data.two} />
<SubComponent id="three" data={data.three} />
<SubComponent id="four" data={data.four} />
// and many more
)
}
const SubComponent = ({id, data}) => {
return (
<div>{data}</div>
)
}
选项三
// call the reducer in the subcomponent
const MainComponent = () => {
return (
<SubComponent id="one" />
<SubComponent id="two" />
<SubComponent id="three" />
<SubComponent id="four" />
// and many more
)
}
const SubComponent = ({id}) => {
const { data } = useMyReducer()
const myData = data[id]
return (
<div>{myData}</div>
)
}
edit:显示useMyReducer
代码-本质上是访问上下文,还有react的useReducer
和createContext
import { useContext } from 'react'
import { MyContext } from './context'
const useMyReducer = () => {
const context = useContext(MyContext)
if (context === undefined) {
throw new Error('useMyReducer must be used within MyContext')
}
return context
}
export default useMyReducer
// in context.js
export const MyContext = createContext(initialState)
export const MyProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, {})
... // reducer functions
const value = { state, // plus functions etc }
return <MyContext.Provider value={value}>{children}</MyContext.Provider>
}
2条答案
按热度按时间tkclm6bt1#
是的!你是对的,选择2是最正确的方法,因为:
1-仅将所需数据传递到每个组件,避免传递不必要的数据。
2-避免像选项3那样多次调用reducer。在每个组件中调用useMyReducer()可能会影响性能。
3-保持关注点的分离-父组件处理数据获取,子组件只是呈现。
编译后,性能差异可能会减少,但选项2仍然通过仅向每个组件传递相关数据来保持代码的整洁和可维护性。
选项1将不必要的数据传递给每个子节点,而选项3则多次调用reducer。
%%
ADDED
%%比较选项2和选项3:
7bsow1i62#
比较#1和#2,你的例子很简单,没有什么区别。但在更复杂的例子中,我通常倾向于#2,原因如下:
在某个时候,如果SubComponent的任何属性都没有更改,您可能会决定通过跳过SubComponent的呈现来提高性能。如果使用选项1,则对数据的任何部分进行更改都将中断所有子组件上的备忘录。如果使用选项2,则只有一个子组件会中断其备忘录化
1.重用性
如果组件只接受完成其工作所需的最小数据量(即选项2),那么您可以在更广泛的情况下使用该组件。如果您发现自己在一个页面上只有一个组件的数据,而这个组件没有 Package 在容器对象中,那么它可以将其传递到SubComponent中,而不必首先将其 Package 在对象中。
关于备选方案3:我最初的答案假设它会导致每个组件都有自己的状态。但是看到代码,我错了。钩子使用
useContext
访问提供程序中的共享状态。选项#3的行为与选项#1类似。如果数据的任何部分发生更改,那么所有子组件都必须重新渲染,即使它们使用React.memo。而且可重用性将降低,因为现在它只能使用来自一个源的数据。