今年早些时候,React团队推出了第一个官方的上下文API。我在博客上介绍了这个新的API,人们得到了足够的、合理的热捧。
我知道人们在实际应用中会有一个共同的抱怨,那就是上下文消费者是一个基于渲染参数的API。 当你需要消费多个上下文和其他基于渲染参数的API(用于逻辑重用)时,这会导致大量的嵌套。因此,我在博文中建议,你可以将所有基于渲染参数的API合并到一个函数组件中,然后进行消费,从而解决这个问题。
const ThemeContext = React.createContext('light')
class ThemeProvider extends React.Component {
/* code */
}
const ThemeConsumer = ThemeContext.Consumer
const LanguageContext = React.createContext('en')
class LanguageProvider extends React.Component {
/* code */
}
const LanguageConsumer = LanguageContext.Consumer
function AppProviders({children}) {
return (
<LanguageProvider>
<ThemeProvider>{children}</ThemeProvider>
</LanguageProvider>
)
}
function ThemeAndLanguageConsumer({children}) {
return (
<LanguageConsumer>
{language => (
<ThemeConsumer>{theme => children({language, theme})}</ThemeConsumer>
)}
</LanguageConsumer>
)
}
function App() {
return (
<AppProviders>
<ThemeAndLanguageConsumer>
{({theme, language}) => (
<div>
{theme} and {language}
</div>
)}
</ThemeAndLanguageConsumer>
</AppProviders>
)
}
尽管这个解决方案由于React组件的可组合性而发挥作用,但我仍然对它不太满意。而且我不是唯一的一个。
我们听到的反馈是,在类组件中采用新的渲染道具API会很困难。因此,我们增加了一个方便的API,可以在类组件中消费一个上下文值。-Reactv16.6.0: lazy, memo and contextType
这个新的便利API意味着,如果你使用一个类组件,并且你只消费一个上下文,你可以简单地定义一个静态属性,称为contextType ,并将其分配给你想要消费的上下文,然后你可以通过this.context 。对于只消耗一个上下文的常见情况来说,这是个很好的技巧。
我已经使用了这个方便的API,我喜欢它。但我对React Hooks对React上下文的未来所产生的影响更加兴奋。让我们用即将到来的(ALPHA!)useContext 钩子重写我们上面的内容。
const ThemeContext = React.createContext('light')
class ThemeProvider extends React.Component {
/* code */
}
const LanguageContext = React.createContext('en')
class LanguageProvider extends React.Component {
/* code */
}
function AppProviders({children}) {
return (
<LanguageProvider>
<ThemeProvider>{children}</ThemeProvider>
</LanguageProvider>
)
}
function App() {
const theme = useContext(ThemeContext)
const language = useContext(LanguageContext)
return (
<div>
{theme} and {language}
</div>
)
}
ReactDOM.render(
<AppProviders>
<App />
</AppProviders>,
document.getElementById('root'),
)
WOWZA!和基于渲染参数的消费者一样强大,这甚至更容易阅读、理解、重构和维护!而且不仅仅是减少了代码。而且,这不仅仅是为了减少代码而减少代码。此外,通常当我们减少代码量的时候,我们也会减少代码能够给我们带来的清晰的交流。但在这种情况下,它的代码更少*,而且*更容易理解。我认为这是一个很大的胜利,也是新钩子API的一个巨大的特点。
React钩子的另一个大特点是它是完全选择的,并且向后兼容。我知道Facebook不能做出会给那些在世界最古老和最大的React代码库工作的工程师带来痛苦的决定,这让我感到非常欣慰。事实上,React已经逐步把我们带到了这个新的钩子世界,这真是太棒了。谢谢React团队!期待正式发布!
总结
React最酷的事情之一是,它允许我们专注于解决现实世界的问题,而通常不需要太接近事物的实现。我已经很久没有经常性地处理跨浏览器或性能问题了。现在React更进一步,简化了事情,所以我写的代码更容易阅读、理解、重构和维护。我就是喜欢这样。这让我想知道,我是否可以对我的代码做一些事情,以简化其他人的事情🤔。
下次再来吧祝您好运!👋