Q:

In ReactFire, how to bind a ref that depends on a property?

I have a React component used like <UserName uid={uid}>, in which I'd like to use the value of a Firebase reference that depends on the uid. Since props can change, it looks like I need to bind the reference in both componentWillMount and componentWillReceiveProps like:
componentWillMount() {
  this.bindAsObject(userRoot.child(this.props.uid).child('name'), 'username');
},

componentWillReceiveProps(nextProps) {
  this.unbind('username');
  this.bindAsObject(userRoot.child(this.props.uid).child('name'), 'username');
},

render() {
  return <span>{this.state.username['.value']}</span>;
},

The React documentation warns against having state depend on props, presumably to avoid exactly this need to update the state from two places.
Is there a better way to do this?

A:

This looks fine. You are anticipating that the uid will change and reacting to it.
Some improvements you could consider:
Adding a uid equality check so that you only rebind if the uid changes
If you need access to other user properties, create a single containing component that binds to the entire user data object and passes down the data as props:
componentWillMount() {
  this.bindAsObject(userRoot.child(this.props.uid), 'user');
},

componentWillReceiveProps(nextProps) {
  if (this.props.uid !== nextProps.uid) {
    this.unbind('user');
    this.bindAsObject(userRoot.child(this.props.uid), 'user');
  }
},

render() {
  return (
    <div>
      <UserName name={this.state.user.name}></UserName>
      <Gravatar email={this.state.user.email}></Gravatar>
    </div>
  );
},

Ideally you want all your fetching/listening code in one component so the lower level components don't need to care how the data was fetched.

