Как использовать хук useContext () внутри компонента, который обернут в HOC? - PullRequest
0 голосов
/ 07 июня 2019

У меня есть компонент Login и компонент App. Компонент App содержит компонент Login в провайдере контекста. Компонент Login в свою очередь оборачивается компонентом высшего порядка withFormik для проверки формы. Когда я пытаюсь использовать хук useContext () в компоненте Login, он не компилируется с ошибкой:

. / SRC / компоненты / Логин / Login.jsx

Строка 12: React Hook «useContext» вызывается в функции «login», которая не является ни компонентом функции React, ни пользовательской функцией React Hook response-hooks / rules-of-hooks

Пробовал также просматривать документы React, но не смог это исправить. (

Login.jsx:

import React, { useContext } from 'react';
import { withFormik, Form, Field } from 'formik';

import { RenderInput, RenderMobileNumberInput } from '../../utils/input.util';
import { isMobile, isPassword } from '../../utils/validation.util';

import AuthContext from '../../store/auth.store';

import '../../styles/login.scss';

const login = props => {
  const authContext = useContext(AuthContext);
  console.log('authContext', authContext);

  return (
    <div className="login-container">
      <div className="login-content">
        <h1 className="header">Agent Login</h1>
        <div className="login-form">
          <Form>
            <div className="input-row">
              <label htmlFor="mobile">Mobile Number</label>
              <Field
                component={RenderMobileNumberInput}
                countrycode="+91"
                name="mobile"
                placeholder="Mobile Number"
                validate={isMobile}
              />
            </div>
            <div className="input-row">
              <label htmlFor="password">Password</label>
              <Field
                type="password"
                component={RenderInput}
                name="password"
                placeholder="Enter Password"
                validate={isPassword}
              />
            </div>
            <button className="btn btn-yellow" type="submit">
              Login
            </button>
          </Form>
        </div>
      </div>
    </div>
  );
};

const FormikApp = withFormik({
  mapPropsToValues(props) {
    return {
      mobile: props.mobile || '',
      password: props.password || '',
    };
  },
  handleSubmit(values) {
    console.log(values);
  },
})(login);

export default FormikApp;

App.jsx:

// Importing required NPM modules
import React from 'react';
import { withRouter, Switch, Route } from 'react-router-dom';

// Importing local modules & components
import Login from './components/login/Login';

import AuthContext from './store/auth.store';

// Impoting stylesheets
import './App.scss';

function App() {
  return (
    <AuthContext.Provider value={‌{ isAuthenticated: false }}>
      <div className="App">
        <Switch>
          <Route path="/" exact component={Login} />
        </Switch>
      </div>
    </AuthContext.Provider>
  );
}

export default withRouter(App);

auth.store.js:

import { createContext } from 'react';

const initialContext = {
  user: null,
  isAuthenticated: false,
};

const authContext = createContext({ ...initialContext });

export default authContext;

index.js:

/* eslint-disable react/jsx-filename-extension */
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

import './index.scss';
import App from './App';
import * as serviceWorker from './serviceWorker';

// Importing store contexts
import AuthContext from './store/auth.store';

ReactDOM.render(
  <BrowserRouter>
    <AuthContext.Provider value={{}}>
      <App />
    </AuthContext.Provider>
  </BrowserRouter>,
  document.getElementById('root')
);

serviceWorker.unregister();

1 Ответ

0 голосов
/ 07 июня 2019

Ошибка говорит именно то, что нужно / хочет сказать. Hook может вызываться только внутри функционального компонента React. https://reactjs.org/docs/hooks-rules.html

Пока вы пишете свой login компонент как функциональный компонент, оберните его с помощью withForm HOC, превратив его в компонент класса. Вы должны прочитать исходный код withFormik, чтобы увидеть его: https://github.com/jaredpalmer/formik/blob/next/src/withFormik.tsx.

По сути, то, что делает withFormik HOC (и многие другие HOC делают то же самое), заключается в том, чтобы обернуть ваш компонент внутри компонента класса. Это делается таким образом, чтобы дополнительные компоненты (обычно называемые injected props) могли быть переданы вашему компоненту.

Чтобы решить вашу проблему, вы должны избегать использования ответных хуков с withFormik HOC. Вы можете использовать компонент Formik вместо withFormik HOC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...