使用新的 React hook useContext 的正确方法是什么?

What is the right way to use new React hook useContext?

我在理解使用 React Context 的新方法时遇到了一些困难 API。 我有一个带有自定义 class Firebase 的应用程序。现在我想做一个钩子来传递它。在我使用 HOC (higher-order Component) 和 context.

之前

我的问题

  1. 我需要使用 HOC 还是一种新方法?
  2. 我需要 Context.Provider 还是新的 Hook?
  3. 我需要将默认值声明为 null 还是我可以传递我的对象 来自 context.js
  4. 如何在我的代码中使用新的 Hook 而不是 HOC?

这是我的代码,其中包含一些与问题相关的评论

// context.js this is my hoc
// index.jsx
import App from './App'
import Firebase, { FirebaseContext } from './components/Firebase'

const FirebaseContext = React.createContext(null)

export const withFirebase = Component => (props) => {
  // I don't need to wrap it to the FirebaseContext.Consumer
  // 1 But do I need this HOC or it's a new way?
  const firebase = useContext(FirebaseContext)
  return <Component {...props} firebase={firebase} />
}

ReactDOM.render(
  // 2 Here I'm lost. Do I need the FirebaseContext.Provider or not?
  // 3 Do I need to declare value her or I should do it in context.js as a default?
  <FirebaseContext.Provider value={new Firebase()}>
    <App />
  </FirebaseContext.Provider>,
  document.getElementById('root'),
)

// App.jsx
// 4 Can I use a new Hook instead of HOC here and how?
import { withFirebase } from './components/Firebase/context'
const App = () => {
    const firebase = this.props.firebase // But should be useContext(FirebaseContext) or something like this?
    return(...)
}
export default withFirebase(App) // I don't need this with the Hook

感谢任何帮助。

你首先要明白,useContext只是利用了Context,是一个consumer而不是Provider。

回答您的问题

Do I need to use HOC or it's a new way to do this?

您不需要带钩子的 HOC。 Hooks 旨在取代 HOC 和渲染 props 模式。

Do I need the Context.Provider or it's new Hook?

没有等同于 Context.Provider 的钩子。您必须按原样使用它。

Do I need to declare default value as a null or I can pass my Object right from context.js

仅当您不将 value 道具传递给 Context.Provider 时,才会使用 createContext 的默认值。如果传递它,默认值将被忽略。

How can I use a new Hook instead of HOC in mine code?

不要在 HOC 返回的组件中使用 useContext,而是直接在组件中使用它

示例代码

/ context.js this is my hoc
// index.jsx
import App from './App'
import Firebase, { FirebaseContext } from './components/Firebase'

const FirebaseContext = React.createContext(null)

ReactDOM.render(
  <FirebaseContext.Provider value={new Firebase()}>
    <App />
  </FirebaseContext.Provider>,
  document.getElementById('root'),
)

App.jsx

const App = () => {
    const firebase = useContext(FirebaseContext) 
    return(...)
}
export default App;
  1. 我需要使用 HOC 还是一种新方法?

No, you don't need to use HOC as best technique.

Why? Starting from React v7.0, you can use functional-based components. From this version efficient is to use the the latest technique named HOOKS, which were designed to replace class and provide another great alternative to compose behavior into your components.


  1. 我需要 Context.Provider 还是新的 Hook?

Hook like useContext() has a relation with Context.Provider.
Context is designed to share data that can be considered “global”.

The Provider component accepts a value prop to be passed. Every Context come with a Provider.

Context.Provider component available on the context instance is used to provide the context to its child components, no matter how deep they are.


  1. 我是否需要将默认值声明为 null,或者我可以直接从 context.js 传递我的对象?

No, you don't need necessarily to declare a default value.

Example of defining the context in one corner of the codebase without defaultValue.

const CountStateContext = React.createContext() // <-- define the context without defaultValue


  1. 如何在我的代码中使用新的 Hook 而不是 HOC?

index.jsx

import App from './App'

import Firebase, { FirebaseContext } from './components/Firebase'

const FirebaseContext = React.createContext(null)

ReactDOM.render(
  <FirebaseContext.Provider value={new Firebase()}>
    <App />
  </FirebaseContext.Provider>,
  document.getElementById('root'),
)

根组件:App.js,将在何处使用来自上下文的数据:

const App = () => {
    const firebase = useContext(FirebaseContext) 
    return(...)
}
export default App;