React with only es5 features

by Carson Evans

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/styled-components/4.3.1/styled-components.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>

JavaScript

var h = React.createElement;

function format(str, obj) {
  Object.keys(obj).forEach(function(key) {
    str = str.replace('${'+key+'}', obj[key]);
  });
  return str;
}

var color = '#212529';
var fontWeight = 'bold';

var wrapperSc = styled.div([],
  format('color: ${color};', { color: color }),
  format('font-weight: ${fontWeight};', { fontWeight: fontWeight }),
  'margin: 2px;'
);
  
var numberWrapperSc = styled.span([],
  'display: inline-block;',
  'width: 50px;',
  'text-align: center;'
);
  
var buttonSc = styled.button([],
  'background: transparent;',
  'border: none;',
  'padding: 4px 8px;',
  'cursor: pointer;'
);

function FaIcon(props) {
  return h('i', {
    'aria-hidden': 'true',
    className: format('fas fa-${icon}', { icon: props.icon })
  });
}

function Counter(props) {
	return h(wrapperSc, {},
  	h(buttonSc, { onClick: function() { props.onChange(props.value - 1) } },
      h(FaIcon, { icon: 'minus' })
    ),
    h(numberWrapperSc, {}, props.value),
    h(buttonSc, { onClick: function() { props.onChange(props.value + 1) } },
      h(FaIcon, { icon: 'plus' })
    )
  );
}

function App() {
	var counter1State = React.useState(10);
	var counter2State = React.useState(-10);
	return [
  	h(Counter, { value: counter1State[0], onChange: function(newVal) { counter1State[1](newVal) } }),
    h(Counter, { value: counter2State[0], onChange: function(newVal) { counter2State[1](newVal) } })
  ];
}

ReactDOM.render(h(App), document.body);