Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

passing React.createContext() mistakenly as if it were an element causes confusing error #13624

Closed
cellog opened this issue Sep 12, 2018 · 9 comments
Labels
Resolution: Stale Automatically closed due to inactivity Type: Enhancement

Comments

@cellog
Copy link

cellog commented Sep 12, 2018

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

bug

What is the current behavior?

If you're really tired and forget to use a Context.Provider, and instead use the Context as if it were a provider, React (understandably) freaks out, but the error message is confusing. i.e.:

import React from "react";
import ReactDOM from "react-dom";

const Context = React.createContext();

import "./styles.css";

function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Context value={"oops"}>
        <div>duh</div>
      </Context>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

This results in the console looking something like (pasted from codesandbox):

Warning: A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it.
Warning: A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it.
The above error occurred in one of your React components:
Error in sandbox: 
TypeError: render is not a function
Could not consume error: 
Error {}

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

Edit 1wv0ly494l

What is the expected behavior?

An error that (roughly paraphrased) says something along the lines of:

hey idiot, you're trying to use a context directly. You want to use context.Provider. Go take a shower and try again.

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

16.3+

@gaearon
Copy link
Collaborator

gaearon commented Sep 12, 2018

Context itself is actually the same thing as Consumer (although that’s accidental and we wanted to change it to be a Provider later). So that’s why we expect a render function.

Maybe the first warning could be amended to be more suggestive about the causes.

@Simek
Copy link
Contributor

Simek commented Sep 15, 2018

Also worth noting is that documentation suggest good practice using destructuring assignment when initializing Context which prevents from mentioned mistake:
https://reactjs.org/docs/context.html#reactcreatecontext

P.S. @gaearon Maybe all examples on the Context page and in the 16.3 release blog post should be updated according to good practice suggested in createContext method documentation? It seems doable even with multiple contexts using const { Provider: ThemeProvider } = React.createContext(); notation.
https://reactjs.org/docs/context.html#when-to-use-context
https://reactjs.org/blog/2018/03/29/react-v-16-3.html#official-context-api

@engprodigy
Copy link

Context itself is actually the same thing as Consumer (although that’s accidental and we wanted to change it to be a Provider later). So that’s why we expect a render function.

Maybe the first warning could be amended to be more suggestive about the causes.

I think I will take this up. I will update the warning for such instance to be more suggestive about the cause

@engprodigy
Copy link

@gaearon is there any other thing I need to know to be able to resolve this issue. Thanks.

@engprodigy
Copy link

I think this has been updated.
Just saw this error log
"Warning: Rendering directly is not supported and will be removed in a future major release. Did you mean to render <Context.Consumer> instead?
in div (created by App)
in App
"

@engprodigy
Copy link

#13829
Follow this pull request for update

@engprodigy
Copy link

engprodigy commented Oct 26, 2018

Also worth noting is that documentation suggest good practice using destructuring assignment when initializing Context which prevents from mentioned mistake:
https://reactjs.org/docs/context.html#reactcreatecontext

P.S. @gaearon Maybe all examples on the Context page and in the 16.3 release blog post should be updated according to good practice suggested in createContext method documentation? It seems doable even with multiple contexts using const { Provider: ThemeProvider } = React.createContext(); notation.
https://reactjs.org/docs/context.html#when-to-use-context
https://reactjs.org/blog/2018/03/29/react-v-16-3.html#official-context-api

I agree with this. The usage below is valid:

const {Provider: ColorProvider, Consumer: ColorConsumer} = React.createContext();

function Welcome() {

            return ( 

                     <ColorConsumer> 
                             {
                                 color =>
                                     <div><h1>Hello, {color} </h1>
                                            <h3> {color}</h3>
                                      </div>    
                                } 
                     </ColorConsumer>
                        );
                  
           } 

function App() {

              return (

                            <ColorProvider value="Green" >
                                 <div>
                                   <Welcome  />
                                 </div>
                             </ColorProvider>

                             );

                       }
ReactDOM.render(<App />, document.getElementById('root'));

@stale
Copy link

stale bot commented Jan 10, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.

@stale stale bot added the Resolution: Stale Automatically closed due to inactivity label Jan 10, 2020
@stale
Copy link

stale bot commented Jan 19, 2020

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!

@stale stale bot closed this as completed Jan 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Stale Automatically closed due to inactivity Type: Enhancement
Projects
None yet
Development

No branches or pull requests

4 participants