「前端架构」使用React进行应用程序状态管理( 二 )


function Counter({count, onIncrementClick}) { return {count}}function CountDisplay({count}) { return The current counter count is {count}}function App() { const [count, setCount] = React.useState(0) const increment = () => setCount(c => c + 1) return ( )}
我们刚刚改变了谁对我们的国家负责 , 这真的很简单 。 我们可以一直提升状态 , 直到我们的应用程序的顶端 。
“当然肯特 , 好吧 , 但是道具钻的问题呢?”
好问题 。 您的第一道防线就是改变构建组件的方式 。 利用组件组成 。 也许不是:
function App() { const [someState, setSomeState] = React.useState('some state') return ( <> )}
你可以这样做:
function App() { const [someState, setSomeState] = React.useState('some state') return ( <>logo={} settings={} /> )}
如果这不是很清楚(因为它是超级做作) , 迈克尔杰克逊有一个伟大的视频 , 你可以看 , 以帮助澄清我的意思 。
不过 , 最终 , 即使是组合也不能为您做到这一点 , 所以您的下一步是跳转到React的Context API中 。 这实际上是一个“解决方案” , 但很长一段时间以来 , 这个解决方案是“非官方的” 。 正如我所说 , 很多人求助于react redux , 因为它使用我所指的机制解决了这个问题 , 而不必担心react文档中的警告 。 但是 , 既然context是React API的一个官方支持的部分 , 那么我们可以直接使用它而没有任何问题:
// src/count/count-context.jsimport * as React from 'react'const CountContext = React.createContext()function useCount() { const context = React.useContext(CountContext) if (!context) { throw new Error(`useCount must be used within a CountProvider`) } return context}function CountProvider(props) { const [count, setCount] = React.useState(0) const value = http://kandian.youth.cn/index/React.useMemo(() => [count, setCount], [count]) return }export {CountProvider, useCount}// src/count/page.jsimport * as React from 'react'import {CountProvider, useCount} from './count-context'function Counter() { const [count, setCount] = useCount() const increment = () => setCount(c => c + 1) return {count}}function CountDisplay() { const [count] = useCount() return The current counter count is {count}}function CountPage() { return ( )}
注意:这个特定的代码示例非常做作 , 我不建议您使用上下文来解决这个特定的场景 。 请阅读支柱钻井 , 以获得更好的理解为什么支柱钻井不一定是一个问题 , 往往是可取的 。 不要太快接触上下文!
这种方法的酷之处在于 , 我们可以将更新状态的常用方法的所有逻辑放在useCount钩子中:
function useCount() { const context = React.useContext(CountContext) if (!context) { throw new Error(`useCount must be used within a CountProvider`) } const [count, setCount] = context const increment = () => setCount(c => c + 1) return { count, setCount, increment, }}
你也可以很容易地用这个来说明:
function countReducer(state, action) { switch (action.type) { case 'INCREMENT': { return {count: state.count + 1} } default: { throw new Error(`Unsupported action type: ${action.type}`) } }}function CountProvider(props) { const [state, dispatch] = React.useReducer(countReducer, {count: 0}) const value = http://kandian.youth.cn/index/React.useMemo(() => [state, dispatch], [state]) return }function useCount() { const context = React.useContext(CountContext) if (!context) { throw new Error(`useCount must be used within a CountProvider`) } const [state, dispatch] = context const increment = () => dispatch({type: 'INCREMENT'}) return { state, dispatch, increment, }}
这为您提供了极大的灵活性 , 并将复杂性降低了一个数量级 。 在这样做的时候 , 要记住以下几点:

  • 并非应用程序中的所有内容都需要处于单个状态对象中 。 保持逻辑上的分离(用户设置不必与通知处于同一上下文中) 。 使用此方法将有多个提供程序 。
  • 不是所有的上下文都需要全局访问!让状态政府尽可能靠近需要的地方 。
关于第二点的更多信息 。 你的应用程序树可能如下所示:
function App() { return ( )}function Notifications() { return (