4

I have a functional component (written in Typescript) that needs to pass a handler function down to a child component. Here is a scaled down version of the parent function:

type Props = { handleLocationChange(): void };

const Sidebar: React.FC<Props> = (props) => { 
 const handleLocationChange = () => {
    console.log('Location Changed.');
  };
return (
   <>
      <Search handleLocationChange={handleLocationChange} /> 
   </>
)
}

In VS Code the search component shows an error:

Type '{ handleLocationChange: () => void; }' is not assignable to type 'IntrinsicAttributes & { children?: ReactNode; }'. Property 'handleLocationChange' does not exist on type 'IntrinsicAttributes & { children?: ReactNode; }'.ts(2322)

Any help would be much appreciated. I am sure I am missing something small.

Josh Scott
  • 3,790
  • 7
  • 29
  • 31
  • I think you can't invoke the function at definition. Try without invoke function: { handleLocationChange: void } – Joao Polo Nov 17 '19 at 04:25

3 Answers3

7

You need to declare the prop type in Search Component and declare type to parameter too:

//use this type to both components (children and parent)
interface FuncProps {
    //here you can declare the return type (here is void)
    handleLocationChange: (values: any) => void;
}
//children start
// here are the tip, define the type in the React.FC and in the FC's parameters itself
const Search: React.FC<FuncProps> = (props: FuncProps) => {
    ... your component behavior and view ...
    return (
        {/*↓↓↓↓ use the prop like this ↓↓↓↓*/}
        <input onClick={props.handleLocationChange('something if you need')}/>
    )
};
//children end

// parent start
const Sidebar: React.FC<Props> = (props: FuncProps) => { 
return (
   <>
      <Search handleLocationChange={props.handleLocationChange} /> 
   </>
)
}
//parent end

I hope this answer can help who wants to use typescript and want to easy your own life passing functions through components (I don't recomend pass functions through many levels).

Danrley Pereira
  • 1,126
  • 14
  • 22
3

You need to declare handleLocationChange as a prop on the Search component

Daniel Duong
  • 1,084
  • 4
  • 11
  • 3
    This should be a comment – Alwaysblue Nov 17 '19 at 05:15
  • You have declared `type Props` for Sidebar which is the wrong component. Instead declare `type Props` on your Search component. That takes handle locationChange as a prop. You have a typeError because Search is receiving a prop it doesn't recognise. Search doesn't take locationChange according to the type declaration. – Daniel Duong Nov 18 '19 at 06:41
0

Code your handler like a function, this way

function handleLocationChange(){
    console.log('Location Changed.');
  };

Then it should work

tareq aziz
  • 749
  • 4
  • 11