Home > Back-end >  Pass state between Parent and Child components in React/Typescript
Pass state between Parent and Child components in React/Typescript

Time:10-08

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

  1. You need to pass setVisible function instead of visible.
  2. 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

  • Related