2

I'm pretty new to React, and I want to make sure my process here is correct:

In this simple example, I've got a MsgBox component which can maintain its own text state. When I click a button in that MsgBox, its current value should get sent up to the parent.

var MsgBox = React.createClass({
  getInitialState() {
    return {msg: ''}
  },

  handleKeyUp(event) {
    this.setState({msg: event.target.value});
  },

  sendUp() {
    var inp = React.findDOMNode(this.refs.txt);

    this.props.msgSetter(inp.value);
  },

  render() {
    return (
      <div className="msgbox">
        <input onKeyUp={this.handleKeyUp} ref="txt" />
        <button onClick={this.sendUp}>Send it up!</button>
        <div className="echo">{this.state.msg}</div>
      </div>
    )
  }
});

var Hello = React.createClass({
    getInitialState() {
      return {latestMessage: 'N/A'}
    },

    setLatestMessage(msg) {
      this.setState({latestMessage: msg});
    },

    render() {
      return (
        <div>
          <p>The latest message is {this.state.latestMessage}.</p>
          <div className="msgboxes">
            <MsgBox msgSetter={this.setLatestMessage} />
            <MsgBox msgSetter={this.setLatestMessage} />
            <MsgBox msgSetter={this.setLatestMessage} />
          </div>
        </div>
      )
    }
});

React.render(<Hello name="World" />, document.getElementById('container'));

Fiddle: https://jsfiddle.net/70oo7zzy/1/

Is this pretty much how it's done? What happens if you have this structure:

<Home />
  <StatusBoard />
    <Sector />
      <EventsList />
        <Event />

...and Event had to send something way up to StatusBoard? Do I really have to pass a callback prop from StatusBoard down to Sector, then down to EventsList and finally to each Event? This seems a bit overkill. Or maybe I'm thinking about it the wrong way.

ffxsam
  • 26,428
  • 32
  • 94
  • 144

1 Answers1

4

For a "vanilla" React app, you are actually thinking about it correctly. React documentation basically suggests you try to create your components entirely out of props, that way they are maximally composable, reusable, and declarative.

In practice, for any complex page or hierarchy of components, I haven't found this strategy very practical, as I'm sure you are feeling as well. You would end up with some super huge component at the top-level that knew about everything the descendants would ever need to do, and would have to manage all the callbacks for every action in your application.

The natural next step in a React application that is growing in complexity is to move to the Flux architecture. In the Flux world, you would have Stores that hold your data, and components would fire Actions (via ActionCreators, to use Facebook's lingo verbatim) that the Stores are listening to in order to update that data. Then other components get their state or props from these Stores, and everyone is on the same page.

In your world, I'd envision a MessageStore, which keeps an array of messages perhaps. MsgBox would fire a CREATE_MESSAGE event, which the MessageStore would listen to and add to its internal array. Your top-level Hello component would listen for MessageStore changes, and call MessageStore.getLatestMessage() to get the last message.

There are a number of libraries to help you implement the Flux architecture in your app. Some common ones I know of:

I'm sure there's plenty more to choose from.

None handled everything how I wanted them to, so we rolled our own little helpers at my company that we published here, but if you want more community support, you might try one of the examples listed above.

Sean Adkinson
  • 8,425
  • 3
  • 45
  • 64