【问题标题】:How to use the useContext() hook inside a component which is wrapped within an HOC?如何在包装在 HOC 中的组件内使用 useContext() 挂钩?
【发布时间】:2019-06-07 04:15:16
【问题描述】:

我有一个 Login 组件和一个 App 组件。 App 组件包含上下文 Provider 中的 Login 组件。 Login 组件依次由 withFormik 高阶组件包装以进行表单验证。当我尝试在 Login 组件中使用 useContext() 钩子时,它无法编译并出现错误:

./src/components/login/Login.jsx

第 12 行:React Hook “useContext”在函数“login”中被调用,该函数既不是 React 函数组件也不是自定义 React Hook 函数 react-hooks/rules-of-hooks

也尝试过浏览 React 文档,但无法解决此问题。 :(

登录.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();

【问题讨论】:

    标签: reactjs react-hooks react-context


    【解决方案1】:

    错误准确地说明了它需要/想要说的内容。 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。

    【讨论】:

    • 我尝试完全取消使用 withFormik HOC。刚刚制作了一个只返回一个空白
      的功能组件。它仍然抛出同样的错误。
    • 已修复。问题不在于 withFormik HOC,而在于 React hooks 更新,它强制对组件名称使用大写表示法,即使对于功能组件也是如此。将组件名称 'login' 替换为 'Login' 后,它工作得很好,withFormik HOC 也是如此。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签