【发布时间】:2018-12-21 09:03:20
【问题描述】:
我已经在底部进行了更新
有没有办法维护一个单一的根状态(如 Redux),其中多个 Context API Consumer 工作在他们自己的 Provider 值部分,而不会在每个孤立的更改上触发重新渲染?
已经read through this related question 并尝试了一些变体来测试那里提供的一些见解,但我仍然对如何避免重新渲染感到困惑。
完整代码如下,在线:https://codesandbox.io/s/504qzw02nl
问题在于,根据 devtools,每个组件都会看到“更新”(重新渲染),即使 SectionB 是唯一看到任何渲染更改的组件,即使 b 是唯一的部分改变的状态树。我已经用功能组件和PureComponent 尝试过这个并看到相同的渲染抖动。
因为没有任何东西作为道具传递(在组件级别),所以我看不出如何检测或防止这种情况。在这种情况下,我将整个应用程序状态传递给提供程序,但我也尝试传递状态树的片段并看到同样的问题。很明显,我做错了什么。
import React, { Component, createContext } from 'react';
const defaultState = {
a: { x: 1, y: 2, z: 3 },
b: { x: 4, y: 5, z: 6 },
incrementBX: () => { }
};
let Context = createContext(defaultState);
class App extends Component {
constructor(...args) {
super(...args);
this.state = {
...defaultState,
incrementBX: this.incrementBX.bind(this)
}
}
incrementBX() {
let { b } = this.state;
let newB = { ...b, x: b.x + 1 };
this.setState({ b: newB });
}
render() {
return (
<Context.Provider value={this.state}>
<SectionA />
<SectionB />
<SectionC />
</Context.Provider>
);
}
}
export default App;
class SectionA extends Component {
render() {
return (<Context.Consumer>{
({ a }) => <div>{a.x}</div>
}</Context.Consumer>);
}
}
class SectionB extends Component {
render() {
return (<Context.Consumer>{
({ b }) => <div>{b.x}</div>
}</Context.Consumer>);
}
}
class SectionC extends Component {
render() {
return (<Context.Consumer>{
({ incrementBX }) => <button onClick={incrementBX}>Increment a x</button>
}</Context.Consumer>);
}
}
编辑:我知道可能有a bug in the way react-devtools 检测或显示重新渲染。我以一种显示问题的方式expanded on my code above。我现在无法判断我所做的是否真的会导致重新渲染。根据我从 Dan Abramov 那里读到的内容,我认为我正确地使用了 Provider 和 Consumer,但我无法确定这是否属实。我欢迎任何见解。
【问题讨论】:
标签: javascript reactjs react-redux