I am a little confused as to how to update state between parent and child components. I know state needs to be lifted up which is why I have added it to the parent component. So I want to update the boolean value in the child component(can this be done?). I have tried as below but get the error: Cannot invoke an object which is possibly 'undefined'. This expression is not callable.Type 'Boolean' has no call signatures.
Stackblitz example: https://stackblitz.com/edit/react-ts-hzssfh?file=Child.tsx
Parent
import React from 'react';
import Child from '../components/Child';
const Parent: React.FunctionComponent = () => {
const [visible, setVisible] = React.useState<boolean>(false);
const toggle = () => {
setVisible(!visible);
};
return (
<button onClick={toggle}>toggle</button>
<Child visible={visible} />
)
};
export default Parent;
Child
import React from 'react';
interface Icomments {
visible?: boolean;
}
const Child: React.FunctionComponent<Icomments> = (props: Icomments) => {
const handleClick = () => {
props.visible(false);
};
return (
<button onClick={handleClick}>Hide</button>
)
}
export default Child;
CodePudding user response:
The child needs the function that sets the state - not the state value. So you need to pass down to the Child the setVisible
function as a prop.
<Child setVisible={setVisible} />
const Child = ({ setVisible }) => (
<button onClick={() => { setVisible(false); }}>Hide</button>
);
CodePudding user response:
It looks like you are trying to pass the setVisibile function
- You need to pass setVisible function instead of visible.
- in type you are receiving the setVisible as boolean it must be a function with a return type
Define interface as a function as below
interface Icomments {
setVisible(e: boolean): void;
}
Full code Parent
import React from 'react';
import Child from '../components/Child';
const Parent: React.FunctionComponent = () => {
const [visible, setVisible] = React.useState<boolean>(false);
const toggle = () => {
setVisible(!visible);
};
return (
<button onClick={toggle}>toggle</button>
<Child setVisible={setVisible} />
)
};
export default Parent;
Child
import React from 'react';
interface Icomments {
setVisible(e: boolean): void;
}
const Child: React.FunctionComponent<Icomments> = (props: Icomments) => {
const handleClick = () => {
props.setVisible(false);
};
return (
<button onClick={handleClick}>Hide</button>
)
}
export default Child;
Try this