Skip to content
Advertisement

React Functional Component Parent and Child – Unhandled Rejection (TypeError): X is not a function

  • I have a parent app which contains a handler function (handleChallengeSave).
  • The handler function triggers a useState (setSavedChallenge) in the parent.
  • The handler function is passed down as props to the child.

I’m getting an ‘Unhandled Rejection (TypeError): X is not a function’ error. However if I change nothing other than moving the state to the child, it works.

Eg:

This doesn’t work:

Parent (App.js)

const App = () => {
const [savedChallenge, setSavedChallenge] = useState("");

const handleChallengeSave = (challenge) => {
    setSavedChallenge(challenge);
  };

return (
    <>
      <Router>
        <Route
          path="/"
          exact
          component={Home}
          handleChallengeSave={handleChallengeSave}
/>
</Router>
    </>
  );
};

The Child (Home.js)

const Home = ({ handleChallengeSave }) => {

  const getRequestUserChallengeDb = async () => {
    await axios
      .get(`${USER_CHALLENGE_DB_LINK}/${STRAVA_ID}`)
      .then((res) => {
        if (res.status === 200) {
          console.log("Yes keen bean! You're in a challenge.");
          let yourCurrentChallenge = res.data.currentChallenge;
          handleChallengeSave(yourCurrentChallenge);
        }
        if (res.status === 201) {
          console.log(
            "You ain't in a challenge mate. Head to the challenges page to join one!"
          );
        }
      })
      .catch((error) => {
        throw error;
      });
  };

  getRequestUserChallengeDb();

 return (
    <>
      <Navbar />
      <div className="homepage_container">
        <h2>Hi {window.localStorage.firstName}</h2>
      </div>
      <Challengebutton />
    </>
  );
};

export default Home;

Any help MUCH appreciated!

Advertisement

Answer

Issue

The Route component doesn’t pass additional props on to children.

Solution

Render Home on the render prop to pass in additional props.

<Router>
  <Route
    path="/"
    exact
    render={(routeProps) => (
      <Home
        {...routeProps}
        handleChallengeSave={handleChallengeSave}
      />
    )}
  />
</Router>

Or render Home as a child component.

<Router>
  <Route
    path="/"
    exact
  >
    <Home
      {...routeProps}
      handleChallengeSave={handleChallengeSave}
    />
  </Route>
</Router>
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement