Home > Back-end >  passing down boolean object to a child component in react
passing down boolean object to a child component in react

Time:04-19

I am trying to refactor some react-typescript code and I want to make one general component, and call it with different parameters several times, instead of having several components that work in the same way.

So I am using redux as well, and the way it works is that in each component I call the redux state, and now I want to do it differently. I have made a component that is called DrawerItems and in there I have defined :

type DrawerItemProps = {
    open: boolean,
    tabs: boolean[],
  }

const DrawerItems = ({ open, tabs }: DrawerItemProps) => {
.
.
.
}

in my parent component I have

  const jaTabs = useSelector((state: TabState) => state.JA.tabs);
  const checkedOpen = useSelector((state: TabState) => state.JA.open);

and then I want to pass the to my child component like:

<DrawerItems open={checkedOpen } tabs={jaTabs } />

this generates the error:

Type '{ trunk: boolean; hip: boolean; knee: boolean; ankle: boolean; }' is missing the following properties from type 'boolean[]': length, pop, push, concat, and 29 more.

My state looks like this:

export interface TabState {
    ja: {
        open : boolean;
        tabs : {
            trunk: boolean;
            hip: boolean;
            knee: boolean;
            ankle: boolean;
        }
    }
    //=================
    fp: {
        open : boolean;
        tabs : {
            clearanceSwing: boolean;
            footOrientation: boolean;
        }
    }
    //=================
    gt: {
        open : boolean;
        tabs : {
            gaitWidth: boolean;
            centerOfMass: boolean;
            eCenterOfMass: boolean;
        }
    }
    //=================
    tm: {
        open : boolean;
        tabs : {
            gaitSpeed: boolean;
            stancePhaseDuration: boolean;
            swingPhaseDuration: boolean;
                }
    }
    //=================
    distance: {
        open : boolean;
        tabs : {
            stepLength: boolean;
            strideLength: boolean;
            distanceWalked: boolean;
        }
    }
}

how can I correctly pass the boolean array down to my child component? I want to be able to pass the tabs everytime to my DrawerItem how can I do that?

CodePudding user response:

You are getting the error because you are giving to tabs a different type to what really is. Here,

tabs: boolean[]

You are saying that tabs is an array of boolean. However here:

tabs : {
 trunk: boolean;
 hip: boolean;
 knee: boolean;
 ankle: boolean;
}

You are saying that tabs is an object with those keys. So what you can do is creating an interface that you can import in your DrawerItems component:

export interface ITabs{
 trunk: boolean;
 hip: boolean;
 knee: boolean;
 ankle: boolean;
}
tabs: ITabs;

CodePudding user response:

In your type declaration you declare tabs as a boolean array

type DrawerItemProps = {
    open: boolean,
    tabs: boolean[],
  }

But in your interface you declare the tabs as an object

export interface TabState {
    ja: {
        open : boolean;
        /// Here v
        tabs : {
            trunk: boolean;
            hip: boolean;
            knee: boolean;
            ankle: boolean;
        }
    }
// ...

The type error basically tells you that you pass the the wrong prototype (object instead of array) that's why the error states properties are missing.

I don't know what your further implementation is, so depending on that you could choose to use either objects or arrays.

CodePudding user response:

I would do the refactor in this way. Also you try to assign type of object in array type

export interface Tabs {
   trunk: boolean;
   hip: boolean;
   knee: boolean;
   ankle: boolean;
 }
    

export interface TabState {
    ja: {
        open : boolean;
        tabs : Tabs
    }
    //=================
    fp: {
        open : boolean;
        tabs : {
            clearanceSwing: boolean;
            footOrientation: boolean;
        }
    }
    //=================
    gt: {
        open : boolean;
        tabs : {
            gaitWidth: boolean;
            centerOfMass: boolean;
            eCenterOfMass: boolean;
        }
    }
    //=================
    tm: {
        open : boolean;
        tabs : {
            gaitSpeed: boolean;
            stancePhaseDuration: boolean;
            swingPhaseDuration: boolean;
                }
    }
    //=================
    distance: {
        open : boolean;
        tabs : {
            stepLength: boolean;
            strideLength: boolean;
            distanceWalked: boolean;
        }
    }
}

And in react component pass type in this way

type DrawerItemProps = {
    open: boolean,
    tabs: Tabs,
  }

const DrawerItems = ({ open, tabs }: DrawerItemProps) => {
.
.
.
}

CodePudding user response:

It's happening because u are passing to DrawerItems tab param an object with the type of "TabState ja prop", but define type of tab as boolean[].

You can solve this problem using generics

type DrawerItemProps<T> = {
    open: boolean,
    tabs: T,
}

function DrawerItems<T>({ open, tabs }: DrawerItemProp) {
.
.
.
}

Or using pipe with Lookup Types to extract nested types in TabState, something like this:

type DrawerItemProps = {
    open: boolean,
    tabs: TabState['ja']['tabs'] |  TabState['fp']['tabs'] | TabState['gt']['tabs'] ...etc
}

  • Related