React: Function components do not support contextType.

Created on 1 Nov 2018  路  9Comments  路  Source: facebook/react

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

Warning: withRouter(RegisterModal): Function components do not support contextType.

What is the expected behavior?

No error

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

16.6.0

https://codesandbox.io/s/01zl4m022v

Unfortunately, I'm unable to reproduce this in codesandbox...

import React, { Component } from "react";
import { withRouter } from "react-router-dom";
import ErrorContext from "./ErrorContext";

class RegisterModal extends Component {
  render() {
    return <div>test</div>;
  }
}

RegisterModal.contextType = ErrorContext;

// this doesn't cause any error:
// export default RegisterModal;
// this causes an error:
export default withRouter(RegisterModal);

For some reason, whenever I wrap my RegisterModal component with withRouter, I get this error: Warning: withRouter(RegisterModal): Function components do not support contextType.. The weird thing is I'm setting contextType directly on the class, before the HOC function is applied.

Most helpful comment

was usings contextType = ThemeContext for example on my component as context api suggests, was on react 16.6.1 and it still had this issue...

All 9 comments

This appears to get rid of the error for some reason:

const WrappedClass = withRouter(RegisterModal);
WrappedClass.WrappedComponent.contextType = ErrorContext;
export default WrappedClass

Are you using static class properties syntax?

My best guess is that React Router copies the contextType from the inner class because it's static. That was fixed in https://github.com/mridgway/hoist-non-react-statics/pull/62 so you should get the fix automatically when you update the lockfile.

was usings contextType = ThemeContext for example on my component as context api suggests, was on react 16.6.1 and it still had this issue...

@bjm88 Yes, I'm still having this issue as well.

I had to avoid statics and just use a wrapping component with jsx tags.

Yes, the issue persists even after updating hoist-non-react-statics. See the issue discussed here

Is there any solution to this issue?
I just updated to 16.6.0 but still facing this issue.
Please suggest any possible working solution.

@kiranvj @techyrajeev

You can use an intermediate Component (function or class) that does not have a contextType and which in turn renders your component which needs the router:

export function withRouterWorkaround(Inner) {
    const Wrapped = (props) => <Inner {...props}/>;
    Wrapped.displayName = `WithRouterWorkaround(${Inner.displayName || Inner.name || '?'})`;
    return withRouter(Wrapped);
}

or as a class

export function withRouterWorkaround(Inner) {
    class Wrapped extends Component {
        render() {
            return <Inner {...this.props}/>;
        }
    }
    Wrapped.displayName = `WithRouterWorkaround(${Inner.displayName || Inner.name || '?'})`;
    return withRouter(Wrapped);
}

TypeScript:

export function withRouterWorkaround<P extends RouteComponentProps<any>>(Inner: ComponentType<P>) {
  const Wrapped: FunctionComponent<P> = (props: P) => <Inner {...props} />;
  Wrapped.displayName = `WithRouterWorkaround(${Inner.displayName || Inner.name || '?'})`;
  return withRouter(Wrapped);
}
Was this page helpful?
0 / 5 - 0 ratings