Home > other >  React functional prop is not a function error
React functional prop is not a function error

Time:11-15

My parent component is where I have a function I pass to the child component: NOTE: Planetdata does not have Redirect but I dont think that shoukd matter


export default function LandingPage() {
    function redirection(){
      console.log("redirecting");
    }
    
    return(
        <>
         ...
        {planetData.map((planet) => (
          <Planet planet={planet} key={planet.id} Redirect={redirection}/>
        ))}
        <Lights />
      </Canvas>
    </>
    )
}

My child component where I want to call the function from:

export default function Planet({ planet: { color, xRadius, zRadius, size, speed, offset,Name = "",Redirect,...props} }) {
  
    return (
      <>
        <mesh ref={planetRef} onClick={(e) => {
          this.Redirect(); //CALLING IT HERE
        }}>
          <sphereGeometry args={[size, 32, 32]} />
          <meshStandardMaterial color={color} />
          {Name != "" && <Html prepend distanceFactor={65}>
            <div className="annotation">{Name}</div>
          </Html> }     
        </mesh>
        <Eliptical xRadius={xRadius} zRadius={zRadius} />
      </>
    );
  }

I tried it without this in child component. The error I get is Redirect is not a function

Descriptive error:

Uncaught TypeError: redirect is not a function
    at Planet (Planet.js:25)
    at renderWithHooks (react-reconciler.development.js:6412)
    at mountIndeterminateComponent (react-reconciler.development.js:9238)
    at beginWork (react-reconciler.development.js:10476)
    at HTMLUnknownElement.callCallback (react-reconciler.development.js:12184)
    at Object.invokeGuardedCallbackDev (react-reconciler.development.js:12233)
    at invokeGuardedCallback (react-reconciler.development.js:12292)
    at beginWork$1 (react-reconciler.development.js:16531)
    at performUnitOfWork (react-reconciler.development.js:15337)
    at workLoopSync (react-reconciler.development.js:15268)
    at renderRootSync (react-reconciler.development.js:15231)
    at performSyncWorkOnRoot (react-reconciler.development.js:14840)
    at react-reconciler.development.js:2546
    at unstable_runWithPriority (scheduler.development.js:468)
    at runWithPriority (react-reconciler.development.js:2495)
    at flushSyncCallbackQueueImpl (react-reconciler.development.js:2541)
    at flushSyncCallbackQueue (react-reconciler.development.js:2528)
    at scheduleUpdateOnFiber (react-reconciler.development.js:14421)
    at Object.updateContainer (react-reconciler.development.js:18229)
    at render (react-three-fiber.esm.js:1568)
    at react-three-fiber.esm.js:1370
    at commitHookEffectListMount (react-dom.development.js:20573)
    at commitLifeCycles (react-dom.development.js:20634)
    at commitLayoutEffects (react-dom.development.js:23426)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
    at invokeGuardedCallback (react-dom.development.js:4056)
    at commitRootImpl (react-dom.development.js:23151)
    at unstable_runWithPriority (scheduler.development.js:468)
    at runWithPriority$1 (react-dom.development.js:11276)
    at commitRoot (react-dom.development.js:22990)
    at performSyncWorkOnRoot (react-dom.development.js:22329)
    at react-dom.development.js:11327
    at unstable_runWithPriority (scheduler.development.js:468)
    at runWithPriority$1 (react-dom.development.js:11276)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
    at flushSyncCallbackQueue (react-dom.development.js:11309)
    at scheduleUpdateOnFiber (react-dom.development.js:21893)
    at dispatchAction (react-dom.development.js:16139)
    at ResizeObserver.callback (web.js:69)
    at later (index.js:27)

CodePudding user response:

you dont have to call that function, you can replace this code,

<mesh ref={planetRef} onClick={(e) => {
          this.Redirect(); //CALLING IT HERE
        }}>

to this, it will work, dont call function, just pass it, you dont even need fat arrow,

<mesh ref={planetRef} onClick={Redirect}}>

CodePudding user response:

Redirect was passed directly as a prop:

<Planet
  planet={planet}
  key={planet.id}
  Redirect={redirection} // <-- passed as prop
/>

You are attempting to destructure Redirect prop from the planet prop object. In other words, you are trying to access it a level too deep.

export default function Planet({
  planet: {
    color,
    xRadius,
    zRadius,
    size,
    speed,
    offset,
    Name = "",
    Redirect, // <-- undefined is not a function!
    ...props
  },
  // <-- but should be here
}) {

You likely meant to destructure Redirect from props and also to spread the rest of the props into props instead of the rest of planet. Move these out to the root prop level.

Also, as pointed out comments above, remove the this as this isn't defined in function components.

export default function Planet({
  planet: { color, xRadius, zRadius, size, speed, offset,Name = ""},
  Redirect,
  ...props
}) {
  return (
    <>
      <mesh ref={planetRef} onClick={Redirect}>
        <sphereGeometry args={[size, 32, 32]} />
        <meshStandardMaterial color={color} />
        {Name != "" && <Html prepend distanceFactor={65}>
          <div className="annotation">{Name}</div>
        </Html> }     
      </mesh>
      <Eliptical xRadius={xRadius} zRadius={zRadius} />
    </>
  );
}
  • Related