Как правильно использовать новый React-хук useContext?
У меня есть некоторые трудности, чтобы понять новый способ использования реагирования Context API. У меня есть приложение с пользовательским классом Firebase. Теперь я хочу сделать крюк, чтобы передать его. До этого я использовал hok и context.
Мои вопросы
- Нужно ли использовать Hoc или это новый способ сделать это?
- Нужен ли мне Context.Provider или это новый Hook?
- Нужно ли объявлять значение по умолчанию как ноль, или я могу передать свой объект прямо из context.js
- Как я могу использовать новый Hook вместо Hok в моем коде?
Вот мой код с некоторыми комментариями, связанными с вопросами
// 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 Hok 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
Любая помощь приветствуется.
4 ответа
Вы должны сначала понять это, useContext
просто использовать контекст и действует как потребитель, а не провайдер.
Ответить на ваши вопросы
Нужно ли использовать Hoc или это новый способ сделать это?
Вам не нужен HOC с крючками. Крючки предназначены для замены HOC и рендеринга реквизита.
Нужен ли мне Context.Provider или это новый Hook?
Не существует хуков, эквивалентных Context.Provider. Вы должны использовать его как есть.
Нужно ли объявлять значение по умолчанию как ноль, или я могу передать свой объект прямо из context.js
Значение по умолчанию для createContext используется только если вы не передаете value
реквизит для Context.Provider
, Если вы передадите его, значение по умолчанию будет проигнорировано.
Как я могу использовать новый Hook вместо Hok в моем коде?
Вместо того, чтобы использовать useContext
в компоненте, возвращаемом HOC, используйте его непосредственно в компоненте
Образец кода
/ 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;
import About from './About'
import React, { createContext, useContext, useState } from 'react'
import {colorThem} from '../App'
const listData =createContext()
const Home = () => {
const [list , seTList]=useState([1,2,3,4,5,6,7,8,9])
const data = useContext(colorThem)
return (
<div>
<h1>I'm From Home {data}</h1>
<listData.Provider value={list}>
<About/>
</listData.Provider>
</div>
)
}
export default Home
export {listData}
import { useContext } from "react"
import { listData } from "./Home"
const About = () => {
const arr = useContext(listData)
console.log(arr)
return (
<div>
<h1>About components </h1>
{
arr.map((item ,index)=><h1 key={index}>{item}</h1>)
}
</div>
)
}
export default About
Вот протестированный код для useContext. В этом примере я обновляю данные формы и отображаю данные формы в другом компоненте.
import React, {createContext, useReducer, useContext} from 'react';
// CREATING THE CONTEXT
const userContext = createContext(null);
// REDUCER FUNCTION FOR UPDATING THE CONTEXT
const reducerFn = (state = [], payload) => {
switch (payload.type) {
case 'FIRST_NAME':
return {...state, formData: {firstName: payload.payload, lastName: state.formData.lastName}}
case 'LAST_NAME':
return {...state, formData: {firstName: state.formData.firstName, lastName: payload.payload}}
default:
return {...state};
}
}
// CONTEXT PROVIDER COMPONENT TO PASS THE CONTEXT VALUE
const AppContextProvider = ({children}) => {
const [state, dispatch] = useReducer(reducerFn, {formData: {firstName: '', lastName: ''}});
return(
<userContext.Provider value={{state, dispatch}}>
{children}
</userContext.Provider>
)
}
// ACTION CREATION
const updateFname = (val) => {
return {
type: 'FIRST_NAME',
payload: val
}
}
const updateLname = (val) => {
return {
type: 'LAST_NAME',
payload: val
}
}
// ACTION CREATION
// FORM COMPONENT AND UPDATING THE FORMDATA USING CONTEXT
const UserForm = () => {
const {state, dispatch} = useContext(userContext)
return (
<>
<div>
<label htmlFor='fname'>First Name</label>
<input type='text' id='fname' onChange={(e) => dispatch(updateFname(e.target.value))}/>
</div>
<div>
<label htmlFor='lname'>Last Name</label>
<input type='text' id='lname' onChange={(e) => dispatch(updateLname(e.target.value))}/>
</div>
</>
)
}
// COMPONENT FOR DISPLAYING THE FORMDATA
const DisplayFormData = () => {
const {state, dispatch} = useContext(userContext);
return(
<div>
<p>First Name is : {state.formData.firstName} and last Name is {state.formData.lastName}</p>
</div>
)
}
// MAIN COMPONENT
function Question3Context(props) {
return (
<div>
<AppContextProvider>
<UserForm />
<DisplayFormData />
</AppContextProvider>
</div>
);
}
export default Question3Context;
- Нужно ли мне использовать HOC или это новый способ сделать это?
Нет, вам не нужно использовать HOC как лучший метод.
Почему? Начиная с React v7.0, вы можете использовать функциональные компоненты. Начиная с этой версии эффективно использовать новейшую технику под названием HOOKS, которая была разработана для замены класса и предоставления еще одной отличной альтернативы для компоновки поведения в ваших компонентах.
- Нужен ли мне Context.Provider или новый хук?
Хук типа useContext() имеет отношение к Context.Provider.
Контекст предназначен для обмена данными, которые можно считать «глобальными».Компонент Provider принимает свойство value для передачи. Каждый контекст поставляется с провайдером.
Компонент Context.Provider, доступный в экземпляре контекста, используется для предоставления контекста его дочерним компонентам, независимо от того, насколько они глубоки.
- Нужно ли мне объявлять значение по умолчанию как нулевое или я могу передать свой объект прямо из context.js?
Нет, вам не обязательно объявлять значение по умолчанию.
Пример определения контекста в одном углу кодовой базы без defaultValue.
const CountStateContext = React.createContext() // <-- определяем контекст без defaultValue
- Как я могу использовать новый хук вместо 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;