<div id="app"></div>
.color {
  width: 100px;
  height: 100px;
  border: none;
}
async function seriousBusinessLogic(pickAColor) {
  const favorite = await pickAColor('Pick your favorite', [
    'steelblue',
    'darkgoldenrod',
    'olivedrab'
  ]);

  const leastFavorite = await pickAColor(
    'Please pick your least favorite of these colors',
    ['aquamarine', 'darksalmon', 'rebeccapurple']
  );

  alert(`You picked ${favorite}, and ${leastFavorite}`);
}

class SomeFarAwayPlaceThatNeedsToDoBusiness extends React.Component {
  constructor() {
    super(...arguments);
    this.state = { colorRequest: null };
    this.doBusiness = this.doBusiness.bind(this);
  }

  async doBusiness() {
    this.setState({ doinBusiness: true });
    await seriousBusinessLogic(this.props.pickAColor);
    this.setState({ doinBusiness: false });
  }

  render() {
    if (this.state.doinBusiness) {
      return null;
    } else {
      return <button onClick={this.doBusiness}>Do Business</button>;
    }
  }
}

class ComplexApp extends React.Component {
  constructor() {
    super(...arguments);
    this.state = {};
    this.startPicking = this.startPicking.bind(this);
  }

  startPicking(question, colors) {
    return new Promise(resolve =>
      this.setState({
        colorRequest: {
          question,
          colors,
          resolve: c => {
            this.setState({ colorRequest: null });
            resolve(c);
          }
        }
      })
    );
  }

  render() {
    return (
      <>
        <SomeFarAwayPlaceThatNeedsToDoBusiness pickAColor={this.startPicking} />
        {this.state.colorRequest && (
          <PickAColorRequestHandler colorRequest={this.state.colorRequest} />
        )}
      </>
    );
  }
}

function PickAColorRequestHandler({ colorRequest }) {
  return (
    <>
      <h2>{colorRequest.message}</h2>
      {colorRequest.colors.map(c => (
        <button
          class="color"
          style={{ backgroundColor: c }}
          onClick={() => colorRequest.resolve(c)}
        />
      ))}
    </>
  );
}

ReactDOM.render(<ComplexApp />, document.querySelector('#app'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js