我有一个无状态的功能组件,它没有道具,并且从React上下文中填充内容。作为参考,我的应用程序使用NextJS,并且是一个同构应用程序。我试图在这个组件上第一次使用React.memo(),但是它始终在客户端页面更改时重新呈现,尽管道具和上下文没有更改。我知道这是由于我放置了控制台日志。
我组件的一个简单示例是:
const Footer = React.memo(() => {
const globalSettings = useContext(GlobalSettingsContext);
console.log('Should only see this once');
return (
<div>
{globalSettings.footerTitle}
</div>
);
});
我什至尝试没有运气地传递第二个参数:
const Footer = React.memo(() => {
...
}, () => true);
任何想法出什么事了吗?
编辑:上下文提供程序的用法_app.js
如下所示:
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
...
return { globalSettings };
}
render() {
return (
<Container>
<GlobalSettingsProvider settings={this.props.globalSettings}>
...
</GlobalSettingsProvider>
</Container>
);
}
}
实际的GlobalSettingsContext文件如下所示:
class GlobalSettingsProvider extends Component {
constructor(props) {
super(props);
const { settings } = this.props;
this.state = { value: settings };
}
render() {
return (
<Provider value={this.state.value}>
{this.props.children}
</Provider>
);
}
}
export default GlobalSettingsContext;
export { GlobalSettingsConsumer, GlobalSettingsProvider };
问题出在哪里
useContext
。每当您的上下文中的任何值更改时,无论您使用的值是否已更改,组件都将重新呈现。解决方案是
withMyContext()
像这样创建一个HOC(即)。通过传递上下文作为道具,而不是在render中使用它,使我们能够隔离出我们实际上关心使用areEqual的变化值。在中渲染期间,无法进行此比较
useContext
。我会大力倡导将选择器作为第二个参数,类似于react-redux的新钩子useSelector。这将使我们能够做类似的事情
const state = useContext(MyContext, ({state}) => state);
谁的返回值只会在状态更改时更改,而不会在整个上下文更改时更改。
但是我只是一个梦想家。
这可能是我目前关于在简单应用程序的钩子上使用react-redux的最大争论。