Mateus Felipe
Mateus Felipe

Reputation: 1161

ES2015: How can I simplify an if statement with assignment?

I am building a React component that returns diverse tags based on a condition. The code is the following:

// Header.jsx

import React from 'react';

const Header = ({...props}) => {
	let Tag;
	if (props.h1)
		Tag = 'h1';
	else if (props.h2)
		Tag = 'h2';
	else if (props.h3)
		Tag = 'h3';
	else if (props.h4)
		Tag = 'h4';
	else if (props.h5)
		Tag = 'h5';
	else
		Tag = 'h6';

	return (
		<Tag>
			{ children }
		</Tag>
	);
}

export default Header;

I though ES2015 would support if as expressions, so I tried let Tag = (if (expression) [...]);, but it seems that it doesn't support. How can I simplify this snippet?

Upvotes: 3

Views: 1104

Answers (3)

Mateus Felipe
Mateus Felipe

Reputation: 1161

I solved my problem by dynamic searching for the tags with regex. The code ended like this:

// Header.jsx

import React from 'react';

const Header = ({children, ...other}) => {
	let Tag = (() => {
		for(let key in other)
			if (/(h[1-6])/.exec(key)) return key;
		return 'h6';
	})();

	return (
		<Tag {...other}>
			{ children }
		</Tag>
	);
}

export default Header;

What do you think about this solution?

Upvotes: 0

Bergi
Bergi

Reputation: 664185

You seem to be looking for the ternary operator (which constitute an expression, not a statement like if, and can be used inside an assignment):

const Tag = props.h1
  ? 'h1'
  : props.h2
    ? 'h2'
    : props.h3
      ? 'h3'
      : props.h4
        ? 'h4'
        : props.h5
          ? 'h5'
          : 'h6';

Of course, the indentation might be improved (outdented to match else if), or you might want to use && and || short-circuiting instead.

However, for what you are doing here I'd recommend to use a loop:

const Tag = (() => {
    for (let p of 'h1,h2,h3,h4,h5'.split(','))
        if (props[p])
           return props[p];
    return 'h6';
})();

Or just store the tag name as a property itself next to the tag content, there's no reason to have 6 different properties for one thing:

export default function Header({children, headingLevel}) {
    const tag = 'h'+headingLevel;
    return (
        <tag>
            { children }
        </tag>
    );
}

Upvotes: 0

dfsq
dfsq

Reputation: 193261

For readability improvement I would say for-loop would be better:

let Tag;

for (let i of [1, 2, 3, 4, 5, 6]) {
    if (Tag = props['h' + i]) break;
}

Upvotes: 3

Related Questions