0

In my render of my ReactJS component, I have a lot of duplication. I would like to be able to remove that duplication.

Here's the trimmed down version of the component:

export default class PageBody extends React.Component {

    constructor(props) {
        super(props);  

        this.state = {
            displayState: 0         
        };      
    }

    render() {

        const whichLayout = this.state.displayState;
        let resultLayout = null;
        switch(whichLayout) {
            case 1:
                resultLayout =  <div><Toolbar /><br /><PortfolioBody /></div>
                break;
            default:
                resultLayout =  <div><Toolbar /><br /><DefaultBody /></div>
                break;
        }

        return (resultLayout);
    }
}

What I thought would be a good idea is to concatenate resultLayout, but that doesn't seem to work:

let resultLayout = <div><Toolbar /><br />;
        switch(whichLayout) {
            case 1:
                resultLayout =  resultLayout + <PortfolioBody />
                break;
            default:
                resultLayout =  resultLayout + <DefaultBody />
                break;
        }
 resultLayout = </div>;

Thoughts?

Thank you Matt

2 Answers 2

1

<PortfolioBody /> is not a string, you cannot concatenate it. It is equivalent to React.createElement(PortfoliaBody), which returns an object.

Instead, assign the part that can change to a variable and include that in the JSX:

export default class PageBody extends React.Component {

    constructor(props) {
        super(props);  

        this.state = {
            displayState: 0         
        };      
    }

    render() {

        const whichLayout = this.state.displayState;
        let resultLayout = null;
        switch(whichLayout) {
            case 1:
                resultLayout =  <PortfolioBody />;
                break;
            default:
                resultLayout =  <DefaultBody />;
                break;
        }

        return (
          <div>
            <Toolbar />
            <br />
            {resultLayout}
          </div>
        );
    }
}

Or more streamlined:

const layouts = {
  1: PortfolioBody,
};

export default class PageBody extends React.Component {

    constructor(props) {
        super(props);  

        this.state = {
            displayState: 0         
        };      
    }

    render() {
        return (
          <div>
            <Toolbar />
            <br />
            {React.createElement(layouts[this.state.displayState] || DefaultBody)}
          </div>
        );
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Its a jsx not a string, since Toolbar is common, so you can render that directly and use the logic for another component.

Write it like this:

render() {

    const whichLayout = this.state.displayState;
    let resultLayout = null;
    switch(whichLayout) {
        case 1:
            resultLayout =  <PortfolioBody />
            break;
        default:
            resultLayout =  <DefaultBody />
            break;
    }

    return (
        <div>
            <Toolbar />
            <br />
            {resultLayout}
        </div>
    );
}

Or you can improve it one more level by putting the switch part in another method and call that method from render.

Like this:

renderComponent(){
    switch(this.state.displayState) {
        case 1: return <PortfolioBody />;
        default: return <DefaultBody />
    }
}

render() {
    return (
        <div>
            <Toolbar />
            <br />
            {this.renderComponent()}
        </div>
    );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.