Reputation: 1184
In my React app I am conditionally rendering views depending on which button is clicked in my menu component by passing the a changeView
method as props from the parent to the menu. The current view is stored as state in the parent component.
I also want to use this same changeView
method to control a button in each conditionally rendered view to go back to the menu on click.
I am currently achieving this as so:
render() {
let view;
switch(this.state.view) {
case 0:
view = (<Menu changeView={this.changeView} />);
break;
case 1:
view = (<View changeView={this.changeView}>Test 1</View>);
break;
case 2:
view = (<View changeView={this.changeView}>Test 2</View>);
break;
default:
view = (<View changeView={this.changeView}>An error has ocurred!</View>);
}
return (
<div>
{view}
</div>
);
}
As you can see I am having to pass the changeView
method individually to each instance of the View
component. Is there any way to set up the View
component so that every instance is passed the changeView
prop without me having to explicitly declare it each time?
Upvotes: 1
Views: 242
Reputation: 191976
All you need is the changing text inside the view. Move the text to an array outside of the component, and select the text by the view index or fallback to the error:
const text = ['', 'Test 1', 'Test 2'];
class Demo extends React.Component {
state = {
view: 1
}
render() {
const { view } = this.state;
const text = text[view] || 'An error has ocurred!';
return (
<div>
{view === 0 ?
<Menu changeView={this.changeView} />
:
<View changeView={this.changeView}>{text}</View>
}
</div>
);
}
}
Upvotes: 0
Reputation: 6233
You can create a function to do that for you,
getView(Component, children){
return <Component changeView = {this.changeView}>{children}</Component>
}
render() {
let view;
switch(this.state.view) {
case 0:
view = getView(Menu)
break;
case 1:
view = getView(View,'Test 1')
break;
case 2:
view = getView(View,'Test 2')
break;
default:
view = getView(View,'An error has ocurred!');
}
return (
<div>
{view}
</div>
);
}
Upvotes: 0
Reputation: 1786
Try moving the switch statement inside the View component
render() {
return (
<div>
{this.state.view === 0 && <Menu changeView={this.changeView} />}
{this.state.view > 0 && <View changeView={this.changeView}>
{() => {
switch (this.state.view) {
case 1:
return 'Test 1';
case 2:
return 'Test 2';
default:
return 'An error has ocurred!';
}
}}
</View>
</div>
);
}
Upvotes: 3
Reputation: 112787
You could change your switch to just change copy and component if needed instead.
render() {
let copy = "";
let Component = View;
switch (this.state.view) {
case 0:
Component = Menu;
break;
case 1:
copy = "Test 1";
break;
case 2:
copy = "Test 2";
break;
default:
copy = "An error has ocurred!";
}
return (
<div>
<Component changeView={this.changeView}>{copy}</Component>
</div>
);
}
Upvotes: 1