Skelli
Skelli

Reputation: 283

Creating a parent 'workspace' component in ReactJS

Using ReactJS, I am trying to create a common workspace component that will have toolbar buttons and a navigation menu. The idea I have is to re-use this component to wrap all other dynamic components that I render in the app.

Currently, I've created a Toolbar and MenuBar components that I then add to each component in the app as such:

<Toolbar/>
<MenuBar/>
<Vendors/>

This does not feel right, since my aim is to have just one component which would be something like:

<Workspace>
<Vendor/>
</Workspace>

However, I am not sure of how to achieve this and whether this is the right approach.

Upvotes: 0

Views: 238

Answers (2)

Amir Rezvani
Amir Rezvani

Reputation: 1504

React offer two traditional ways to make your component re useable

1- High-order Components

you can separate the logic in withWorkspace and then give it a component to apply that logic into it.

function withWorkSpace(WrappedComponent, selectData) {
  // ...and returns another component...
  return class extends React.Component {
 
    render() {
      // ... and renders the wrapped component with the fresh data!
      // Notice that we pass through any additional props
      return <WrappedComponent data={this.state.data} {...this.props} />;
    }
  };
}

const Component = () => {
  
  const Content = withWorkSpace(<SomeOtherComponent />)
  
  return <Content />

}

2- Render Props

or you can use function props then give the parent state as arguments, just in case you need the parent state in child component.

const Workspace = () => {
    state = {}
    render() {
        return (
            <div className="workspace">
                <div className="workspace__toolbar">
                    {this.props.renderTollbar(this.state)}
                </div>
                <div className="workspace__nav">
                   {this.props.renderNavigation(this.state)}
                </div>
                <div className="workspace__content">
                    {this.props.children(this.state)}
                </div>
            </div>
        )
    }
}

const Toolbar = (props) => {
  return <div>Toolbar</div>
}

const Navigation = (props) => {
  return <div>Toolbar</div>
}

class Component = () => {
  
  return (
  <Workspace
    renderNavigation={(WorkspaceState) => <Navigation WorkspaceState={WorkspaceState} />}
    renderTollbar={(WorkspaceState) => <Toolbar {...WorkspaceState} />}
  >
  {(WorkspaceState) => <SomeComponentForContent />}
  </Workspace>
  )
}

Upvotes: 1

Jeremy Harris
Jeremy Harris

Reputation: 24579

As to whether or not it is the right approach is subjective, but I can provide insight into one way to make a "wrapper" type component:

// Your workspace wrapper component
class Workspace {
    render() {
        return (
            <div className="workspace">
                <div className="workspace__toolbar">
                    Toolbar goes here
                </div>
                <div className="workspace__nav">
                    Navgoes here
                </div>
                <div className="workspace__content">
                    {this.props.children}
                </div>
            </div>
        )
    }
}

// Using the component to define another one
class MyComponent {
    render() {
        return (
            <Workspace>
                This is my workspace content.
            </Workspace>
        )
    }
}

You can also look at HOC's or Higher Order Components to wrap things.

Upvotes: 1

Related Questions