Frontend Development 12 min read

Understanding React Component Architecture: From Static Rendering to State Management and Communication

This article walks through building a React‑based popup page by first dividing the UI into small, single‑responsibility components, creating a static version, distinguishing props from state, adding interactive state, and finally enabling component communication using Flux‑style PubSub events.

Architect
Architect
Architect
Understanding React Component Architecture: From Static Rendering to State Management and Communication

React drives efficient UI updates through a virtual DOM, and its fundamental building block is the component. The article uses a popup dialog example to illustrate component mechanisms, communication patterns, and the derived Flux architecture.

After receiving a visual mockup, the page is broken down into a hierarchy of components following the single‑responsibility principle: App contains ImageWrap , BodyWrap , and BusinessComponent ; the latter includes two Dropdown components and two NavButton components.

With the component map defined, a static (non‑interactive) version is written from the bottom up. An example Dropdown component is shown:

var Dropdown = React.createClass({
  propTypes: {
    title: ReactPropTypes.string,
    text: ReactPropTypes.string,
    options: ReactPropTypes.array.isRequired
  },
  render: function() {
    var optionNodes = this.props.options.map(function(option) {
      return (
{option.text}
);
    });
    return (
{this.props.text}
{optionNodes}
);
  }
});

The static version uses only props (e.g., text , title , options ) and no internal state . The article then explains why keeping components stateless when possible simplifies maintenance.

An anti‑pattern example that incorrectly copies a prop into state is presented:

// Wrong example!
var Dropdown = React.createClass({
  propTypes: {
    title: ReactPropTypes.string,
    text: ReactPropTypes.string,
    options: ReactPropTypes.array.isRequired
  },
  // props.text is only an initial value – this is an anti‑pattern
  getInitialState: function() {
    return {text: this.props.text};
  },
  _onClick: function(text) {
    this.setState({text: text});
  },
  render: function() {
    var optionNodes = this.props.options.map(function(option) {
      return (
{option.text}
);
    }, this);
    return (
{this.state.text} // using state to manage displayed text
{optionNodes}
);
  }
});

To make the dropdown interactive, a boolean active flag is added to the component’s state, and a click handler toggles it:

var Dropdown = React.createClass({
  propTypes: {
    text: ReactPropTypes.string.isRequired,
    title: ReactPropTypes.string,
    options: ReactPropTypes.array.isRequired
  },
  getInitialState: function() {
    return {active: false};
  },
  toggleFold: function() {
    this.setState({active: !this.state.active});
  },
  render: function() {
    var optionNodes = this.props.options.map(function(option) {
      return (
{option.text}
);
    });
    return (
{this.props.text}
{optionNodes}
);
  }
});

For communication between components—especially when a grand‑child needs to inform a distant ancestor—the article adopts a Flux‑style event bus using Pubsub.js . The dropdown publishes a select event when an item is clicked:

var Dropdown = React.createClass({
  propTypes: {
    name: ReactPropTypes.string,
    text: ReactPropTypes.string.isRequired,
    title: ReactPropTypes.string,
    options: ReactPropTypes.array.isRequired
  },
  getInitialState: function() { return {active: false}; },
  toggleFold: function() { this.setState({active: !this.state.active}); },
  select: function(id, text) {
    Pubsub('select', {id: id, text: text});
  },
  render: function() {
    var optionNodes = this.props.options.map(function(option) {
      return (
{option.text}
);
    }, this);
    return (
{this.props.text}
{optionNodes}
);
  }
});

The parent BusinessComponent subscribes to this event in its lifecycle methods:

var BusinessComponent = React.createClass({
  componentWillMount: function() {
    this.selectSubscribe = Pubsub.subscribe('select', function(msg, data) {
      // handle selected option data
    });
  },
  componentWillUnmount: function() {
    Pubsub.unsubscribe(this.selectSubscribe);
  },
  render: function() {
    // render child components
  }
});

While this event‑bus approach works for small projects, the article notes that larger applications benefit from a centralized store (the classic Flux pattern) to avoid scattering subscriptions.

Finally, after all components are built and wired together, the complete page matches the original design mockup, offering improved maintainability and extensibility compared to traditional MVC front‑end architectures.

frontendJavaScriptstate managementReactcomponentFlux
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.