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

useEffect causes 'callback is not a function' exception #15647

Closed
kristiandupont opened this issue May 14, 2019 · 15 comments
Closed

useEffect causes 'callback is not a function' exception #15647

kristiandupont opened this issue May 14, 2019 · 15 comments

Comments

@kristiandupont
Copy link

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

What is the current behavior?

useEffect results in the following exception in the console:

Uncaught TypeError: callback is not a function
    at flushFirstCallback (scheduler.development.js:348)
    at flushWork (scheduler.development.js:441)
    at MessagePort.channel.port1.onmessage (scheduler.development.js:188)

I am unable to isolate the problem enough to create a sandbox that reproduces it. I am posting it here in case there is still some value in it (it seems slightly related to react-navigation/react-navigation#5851, gaearon/overreacted.io#460 and even #15194).
This is my component:

const RemoteControlledSliderRaw = ({ activeIndex, currentlyDragging, className, children }) => {
	const [forcedX, setForcedX] = React.useState(null);

	React.useEffect(() => {
		if (currentlyDragging) {
			window._animateItem.update = setForcedX;
		} else {
			if (window._animateItem.update) {
				setForcedX(null);
				window._animateItem.update = null;
			}
		}
	}, [currentlyDragging]);

	return (
		<div>
			<SliderCore activeIndex={activeIndex} forcedX={forcedX} className={className}>
				{children}
			</SliderCore>
		</div>
	);
};

What might be interesting is that I set a global object to point to a setState setter. That can be called from the outside. I am not sure exactly how the exception occurs, but if I comment out the entire useEffect bit, it goes away.

What is the expected behavior?
No exception. Or at least one that provides some explanation as to what is wrong.

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

16.8.6. I don't know if this worked with earlier versions.

@DevJett
Copy link

DevJett commented May 14, 2019

Same problem: using setInterval just doesn’t work as I'd expect with react-native

const [time, setTime] = useState(0);
        useInterval(() => {
            setTime(time +1);
        });

        return (<Text>{time}</Text>);
}

function useInterval(callback) {
    const savedCallback = useRef();

    // Remember the latest function.
    useEffect(() => {
        savedCallback.current = callback;
    }, [callback]);

    // Set up the interval.
    useEffect(() => {
            let id = setInterval(()=>savedCallback.current(), delay);
            return () => clearInterval(id);
    });
}

I'm getting an error says "Callback() it's not a function"

enter image description here

It's working as expected in Reactjs

https://codesandbox.io/s/z69z66kjyx

"dependencies": {
    "react": "16.8.3",
    "react-native": "^0.59.6",
    ...}

@gaearon
Copy link
Collaborator

gaearon commented May 14, 2019

I've seen this happen because of wrong scheduler version. Unfortunately RN didn't have explicit dependency on scheduler version (by mistake). I fixed this on RN master but I don't think it was released yet.

If you see this, try adding "scheduler": "0.14.0" dependency into your project (or, if that breaks your project, try the opposite — "scheduler": "0.13.6").

@gaearon gaearon closed this as completed May 14, 2019
@DevJett
Copy link

DevJett commented May 14, 2019

I have fixed the problem by using useLayoutEffect instead of useEffect it works fine :)

@gaearon
Copy link
Collaborator

gaearon commented May 14, 2019

That’s not a real fix and will likely blow up later. I recommend to fix the underlying problem instead.

@DevJett
Copy link

DevJett commented May 14, 2019

I have installed the new version of React which automaticlly installed "scheduler": "^0.13.6" but I'm still getting the error
Screen Shot 2019-05-14 at 21 05 35
How can I update the scheduler to 0.14.0

@gaearon
Copy link
Collaborator

gaearon commented May 14, 2019

Try adding "scheduler": "0.14.0" to your package.json and re-running your package manager.

@DevJett
Copy link

DevJett commented May 15, 2019

Thank you @gaearon, the bug has been fixed, I just did npm install scheduler@0.14.0 --save

@sedenardi
Copy link

sedenardi commented May 16, 2019

@gaearon Adding that dep didn't fix the issue for me. It seems to crop up when performing an async task in useEffect:

const EnvironmentSelectorScreen = function() {
  const [envs, setEnvs] = useState(null);
  useEffect(() => {
    const load = async function() {
      const res = await getAllEnvs();
      setEnvs(res);
    };
    load();
  }, []);

  if (!envs) {
    return (<Loading />);
  }

  return (
    <View style={style.container}>
      <FlatList
        data={envs}
        renderItem={({ item }) => <Env item={item} />}
      />
    </View>
  );
};

I can try to make an example repo later today that reproduces the issue.

@snettah
Copy link

snettah commented May 17, 2019

Not work for me with react-konva.
I try both 0.14 and 0.13.6

@ejbp
Copy link

ejbp commented Jun 27, 2019

I'm having the same error here with scheduler: "^0.14.0" when using withStyles or makeStyles from material-ui ("@material-ui/styles": "^4.1.2").

I'm using "webpack": "^4.35.0"

I followed what @gaearon recommended, downgraded scheduler to 0.13.6 and it worked.

@Yaolegol
Copy link

Yaolegol commented Oct 9, 2019

Walking around that issue I finded solution:

  1. this problem occurs when there are multiple versions of scheduler in the project,
  2. for check this use npm list scheduler, or yarn why scheduler (more info here)
  3. if you have several versions of scheduler check link above or
  • use with npm this
  • use with yarn like this:
"resolutions": {
    "scheduler": "0.15.0"
  }
  1. in any case after each manipulation with scheduler ALWAYS reload you react app (e.g. npm start)

Crash-- added a commit to cozy/cozy-drive that referenced this issue Oct 25, 2019
It seems that we have a dep to an old version of
scheduler that doesn't work very well with React Hook

see this issue: facebook/react#15647
Crash-- added a commit to cozy/cozy-drive that referenced this issue Oct 28, 2019
It seems that we have a dep to an old version of
scheduler that doesn't work very well with React Hook

see this issue: facebook/react#15647
y-lohse added a commit to cozy/cozy-home that referenced this issue Nov 4, 2019
y-lohse added a commit to cozy/cozy-home that referenced this issue Nov 5, 2019
@jmayergit
Copy link

jmayergit commented Apr 3, 2020

@gaearon Adding that dep didn't fix the issue for me. It seems to crop up when performing an async task in useEffect:

const EnvironmentSelectorScreen = function() {
  const [envs, setEnvs] = useState(null);
  useEffect(() => {
    const load = async function() {
      const res = await getAllEnvs();
      setEnvs(res);
    };
    load();
  }, []);

  if (!envs) {
    return (<Loading />);
  }

  return (
    <View style={style.container}>
      <FlatList
        data={envs}
        renderItem={({ item }) => <Env item={item} />}
      />
    </View>
  );
};

I can try to make an example repo later today that reproduces the issue.

It could be a syntactic error. Like you I am performing an async task is useEffect. This stack overflow post solved my issue which oddly enough was a missing semi-colon

https://stackoverflow.com/questions/42036349/uncaught-typeerror-intermediate-value-is-not-a-function

@Adecodess
Copy link

Thank you @gaearon, the bug has been fixed, I just did npm install scheduler@0.14.0 --save

i am having this issue, i am using yarn and installed sheduler version 0.20.2 but the error still persist

@Sid2202
Copy link

Sid2202 commented Apr 2, 2023

I am having the same issue. I am using npm to install all my packages and everything worked fine, until I included useEffect.

import { useState, useEffect, useCallback } from "react"

This is how I have imported useEffect from react. BTW, I am using Next.js here.

const getAllData = useCallback( async() => {
        await axios.post('http://localhost:5080/api/table', data)
            .then((response) => {
                setTable(response.data)
            })
    })

useEffect=(() => {
        getAllData();
    },[getAllData])

Here is how I have used in useEffect and useCallback in my functions. I am trying to map data that is stored in the table useState

<tbody>
                        {
                            table?.map(({_id,name,email,contact,hobby})=>(
                                <tr key={_id}>
                                    <td>{_id}</td>
                                    <td>{name}</td>
                                    <td>{email}</td>
                                    <td>{contact}</td>
                                    <td>{hobby}</td>
                                </tr>
                            ))
                        }                    
</tbody>

The script actually worked fine when I had not used useEffect and was just calling the function through a button.
Please let me know if I have done something wrong here.

@kemisstep
Copy link

I am having the same issue. I am using npm to install all my packages and everything worked fine, until I included useEffect.

import { useState, useEffect, useCallback } from "react"

This is how I have imported useEffect from react. BTW, I am using Next.js here.

const getAllData = useCallback( async() => {
        await axios.post('http://localhost:5080/api/table', data)
            .then((response) => {
                setTable(response.data)
            })
    })

useEffect=(() => {
        getAllData();
    },[getAllData])

Here is how I have used in useEffect and useCallback in my functions. I am trying to map data that is stored in the table useState

<tbody>
                        {
                            table?.map(({_id,name,email,contact,hobby})=>(
                                <tr key={_id}>
                                    <td>{_id}</td>
                                    <td>{name}</td>
                                    <td>{email}</td>
                                    <td>{contact}</td>
                                    <td>{hobby}</td>
                                </tr>
                            ))
                        }                    
</tbody>

The script actually worked fine when I had not used useEffect and was just calling the function through a button. Please let me know if I have done something wrong here.

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests