5

I have a problem where I'm trying to store a component into my state and also pass a callback function as its props so that it can be called inside CustomComponent. Here's what I did:

state = {
    tabs: [
        { tabID: '1', component: <CustomComponent testCallback={this.callbackHandler} />}
    ]
}


callbackHandler = () => {
    ....
}

But when I try to call the function inside CustomComponent ( this.props.testCallBack() ), it tells me this is not a function.

Is it OK to store a component inside state like this? Basically, I want to build my own tab group component where I can display different components in different tabs. The callback function is used to let the parent component know when it should add a new tab.

I know there are some libraries for tabs, but I'm just curious how I can do it here.

Thanks

Yoope
  • 1,745
  • 2
  • 16
  • 22

2 Answers2

7

You don't want to store JSX in the state. Instead, store the model data for it, and loop through your data to print your elements!

you can do this:

state = {
    tabs: [
        { tabID: '1', callbackFunctionName: callbackFunction1 }
    ]
}

And inside your render method, you can use these data about the tabs you have stored in your state to render your custom component.

render(){
  const { tabs } = this.state;

  return (
    tabs.length > 0 && tabs.map((tab) => {
      return (
        <CustomComponent testCallback={this.tab['callbackFunctionName']} />
      )
    })
  )
}
Sultan H.
  • 2,908
  • 2
  • 11
  • 23
  • Thanks, I ended up creating custom components in the parent component and then pass it to my tab group as props.children. – Yoope Dec 30 '18 at 22:06
5

You shouldn't store the react component in the state, state just use for data:

For example:

  state = {
    tabs: [{ id: 1, content: "hello world", id: 1, content: "hello world 2" }],
  };

And the in render() you can use that data to translate it to the react component:

  render() {
    const tabComponent = this.state.tabs.map((tab) => {
      <CustomComponent
        tabContent={tab.content}
        id={tab.id}
        testCallback={this.callbackHandler}
      />;
    });
    return (<>{ tabComponent }</>);
  }

Hope it helps!!

diedu
  • 19,277
  • 4
  • 32
  • 49
Tony Bui
  • 1,231
  • 7
  • 18