Reputation: 2554
I have a component ContentHeader that I will use in almost each content, it provides a header with title and two buttons, New and Search.
import React from 'react';
import Title from 'components/Title';
import BtnSearch from 'components/BtnSearch';
import BtnNew from 'components/BtnNew';
class ContentHeader extends React.Component {
constructor (props) {
super(props);
}
render () {
return (
<div className='content-header'>
<Title name={this.props.title} />
<ul className='actions'>
<li className='action-item'>
<BtnSearch />
</li>
<li className='action-item'>
<BtnNew />
</li>
</ul>
</div>
);
}
}
export default ContentHeader;
The button components that I use inside the ContentHeader:
// Component Button Search
import React from 'react';
import { NavLink } from 'react-router-dom';
class BtnSearch extends React.Component {
constructor (props) {
super(props);
}
render () {
return (
<a className='btn-actions btn-search' onClick=CUSTOM_REQUEST>
<span className="icon-center"></span>
</a>
)
}
}
export default BtnSearch;
// Component Button New
import React from 'react';
import { NavLink } from 'react-router-dom';
class BtnNew extends React.Component {
constructor (props) {
super(props);
}
render () {
return (
<NavLink to=CUSTOM_REQUEST className='btn-actions btn-new'>
<span className="icon-center"></span>
</NavLink>
)
}
}
export default BtnNew;
Let's say that I will have Projects, Contracts and Widgets main contents and I need to use the ContentHeader inside.
For each main content I will have a different title label, which I can pass by props, since is just one level deep. But also, I will have different requests for each button inside the ContentHeader component, related to the main content that it belongs.
So, how can I pass these different requests to the buttons related to my main content? Props as well? What about if I have a deeper component tree?
PS: As an example I used NavLink and a simple onClick inside my button components with a flag CUSTOM_REQUEST
Thanks!
Upvotes: 1
Views: 93
Reputation: 3687
If you are using plain react and nesting is too large, then it will become very difficult to pass props to every level . In that case you can use context API from react.
You can read it here : how-to-use-context
But it is not encouraged to use context.
You can read it here: why not to use context
You can try the following approach
function Wrapper(newBtnAction, searchBtnAction, label, props) {
return ( < ContentHeader {...props
}
label = {
label
}
newBtnAction = {
newBtnAction
}
searchBtnAction = {
searchBtnAction
}
/>
)
}
Now you can use the wrapped component anywhere just you need to pass proper function bind with store.dispatch
Lets say you have a component B ,C, D, E you can use it like this
class B extends React.Component {
render() {
// get proper actions here
const {
newBtnAction,
searchBtnAction,
label
} = this.props
return ( < C >
< D >
< E > {
Wrapper(newBtnAction, searchBtnAction, label, this.props)
} < /E> < /D> < /C>
)
}
}
we call this concept as higher order components in react. This is basically a design pattern that comes out of react component approach
Note: Mind brackets, not executed the code
Upvotes: 1
Reputation: 362
If I understand your question correctly, you need to be able to pass a specific request to the respective ContentHeader component based on the type of content.
You can definitely just pass that request function via props to the child button of that page/content component.
import React from 'react';
import Title from 'components/Title';
import BtnSearch from 'components/BtnSearch';
import BtnNew from 'components/BtnNew';
class ContentHeader extends React.Component {
constructor (props) {
super(props);
}
render () {
const { myRequestFunc } = this.props
//...or if not es15
var myRequestFunc = this.props.myRequestFunc
return (
<div className='content-header'>
<Title name={this.props.title} />
<ul className='actions'>
<li className='action-item'>
<BtnSearch />
</li>
<li className='action-item'>
<BtnNew requestFunc={myRequestFunc} />
</li>
</ul>
</div>
);
}
}
export default ContentHeader;
That is the easy way, anyhow. You could - depending on the size of your application - explore Redux, React-Redux and Redux-Thunk or Redux-Saga to avoid the inevitable passing of props down several levels. Checkout using redux with react
Upvotes: 1