Reputation: 283
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
Reputation: 1504
React offer two traditional ways to make your component re useable
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
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