React: Rendered fewer hooks than expected. (with update, see second post)

Created on 16 Nov 2018  Â·  2Comments  Â·  Source: facebook/react

Do you want to request a feature or report a bug?
Bug
What is the current behavior?

Rendered fewer hooks than expected. This may be caused by an accidental early return statement.
â–¶ 17 stack frames were collapsed.
MediaQueryList.listener
src/hooks/media.ts:103
  100 | )
  101 | const listener = () => {
  102 |   console.log( mediaQueryList.matches )
> 103 |   setMatches( mediaQueryList.matches )
      | ^  104 | }
  105 | 
  106 | useEffect( () => {

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:

What is the expected behavior?
Just works
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
16.7-alpha0 / MacOS High Sierra

I have the following useMedia query:

export function useMedia( query: string | Json2mq | Json2mq[], defaultMatches = true ): boolean {
  const [ matches, setMatches ] = useState( defaultMatches )
  const mediaQueryList = window.matchMedia(
    typeof query === 'string' ? query : json2mq( query ),
  )
  const listener = () => {
    setMatches( mediaQueryList.matches )
  }

  useEffect( () => {

    mediaQueryList.addListener( listener )

    return () => {
      mediaQueryList.removeListener( listener )
    }
  }, [] )

  return matches
}

It is being used in a component

export default ( {current, render}: DashNavProps ) => {
  const [ route, setRoute ] = useState<NavItems>( current )
  const showSmallNav = useMedia( {maxWidth: 640}, false )
  return (
    route !== current
      ? <Redirect push to={ route[ 0 ] === '/' ? route : `/dashboard/${route}`} />
      :  <Foo setRoute={setRoute} />
  )
}

Why is this happening? BTW, Foo directly calls setRoute

Most helpful comment

I figured out the problem; it is related to rendering JSX from a function without using React.createElement. For example

<Foo>
  { getJsx() }
</Foo>

The getJsx function acts sort of like a component, but it isn't. Hooks must be used only within components also executed as components.

All 2 comments

I figured out the problem; it is related to rendering JSX from a function without using React.createElement. For example

<Foo>
  { getJsx() }
</Foo>

The getJsx function acts sort of like a component, but it isn't. Hooks must be used only within components also executed as components.

I have this error and can't fixed it
Rendered fewer hooks than expected. This may be caused by an accidental early return statement.
â–¶ 22 stack frames were collapsed.
(anonymous function)
src/Components/functionTools/functionProps.js:783
780 |
781 | export function addSearchLoading(data) {
782 | return async dispatch => {

783 | dispatch({
784 | type: "ADD_LOADING_SEARCH",
785 | data: data
786 | });

Was this page helpful?
0 / 5 - 0 ratings