title: React update parent component when child changes the Context
body: <p>I have four React components:</p>
  
  <ul>
  <li>An overall parent (<code>App</code> or similar)</li>
  <li>A <code>Header</code> child, called by <code>App</code></li>
  <li>A <code>Profile</code> page</li>
  <li>A <code>LogoutLink</code>, called by <code>Profile</code></li>
  </ul>
  
  <p>I am implementing a User authentication/login system using <a href="https://auth0.com" rel="nofollow">Auth0</a>. When the user logs in (via a Login button in the <code>Header</code>), <code>App</code> changes the <code>Context</code> of the <code>User</code> object to include all the data retrieved from Auth0. This user data is then accessible to any part of the system which requires it.</p>
  
  <p>When logged in, the UI automatically updates (using <code>Context</code> changes) so that the <code>Header</code> is now showing "Hey there {name}" rather than "Login" as before. This is also a link leading to the <code>Profile</code> page/component (using React Router's <code>&lt;Link to="/profile&gt;&lt;/Link&gt;</code> element).</p>
  
  <p>On the <code>Profile</code> page there is a <code>LogoutLink</code>. When clicked, this logs the user out, and returns to the home page. It should also update the UI automatically to change the message in the <code>Header</code> back from "Hey there {name}" to "Login". This is done by <code>Context</code> changes again. However, this feature doesn't actually work - the user is successfully logged out, but to see the change described just above, the user needs to refresh the whole page. <strong><code>this.context.user</code> is not being updated and sent back to <code>Profile</code> and <code>Header</code>.</strong> I know this is because of Redux and it's one-way data flow (i.e data can only go downwards, not up), but I need to find a way around it.</p>
  
  <p>Here is the basic code I have:</p>
  
  <p><code>LogoutLink.js</code></p>
  
  <pre><code>export default class LogoutLink extends React.Component {
  
    constructor(props) {
      super(props);
      this.onClick = this.onClick.bind(this);
      this.state = {
        user: null,
      };
    }
  
    static propTypes = {
      value: React.PropTypes.string,
    }
  
    static contextTypes = {
      user: React.PropTypes.object,
    } // get context so this.context is available to get initial user data (before logout)
  
    static childContextTypes = {
      user: React.PropTypes.object,
    }
  
    getChildContext() {
      return {user: this.state.user}
    } // these two are for updating context
  
    componentWillMount() {
      this.setState({ user: this.context.user });
    } // set the internal LogoutLink state
  
    onClick() {
      this.setState({ user: null }); // set the internal user state to null following logout
    }
  
    renderLogoutLink() {
      const {value} = this.props;
      const {user} = this.state;
      if (user != null) {
        return &lt;Link to="/profile" onClick={this.onClick}&gt;{value}&lt;/Link&gt;
      } else {
        return &lt;span&gt;You're already logged out!&lt;/span&gt;
      }
    }
  
    render() {
      return &lt;span&gt;{this.renderLogoutLink()}&lt;/span&gt;
    }
  
  }
  </code></pre>
  
  <p><code>Header.js</code>:</p>
  
  <pre><code>export default class Header extends React.Component { // eslint-disable-line react/prefer-stateless-function
    constructor(props) {
      super(props);
      this.showLock = this.showLock.bind(this); // lock is the Auth0 module responsible for Login, also passed down by context
    }
  
    static contextTypes = {
      user: React.PropTypes.object,
      lock: React.PropTypes.object,
    }
  
    showLock() {
      const {lock} = this.context;
      lock.show();
    }
  
    shouldComponentUpdate(nextProps, nextState, nextContext) {
      if (this.context.user == null &amp;&amp; nextContext.user != null) {
        return true;
      } else if (this.context.user != null &amp;&amp; nextContext.user == null) {
        return true;
      }
      return false;
    } // after the LogoutLink is clicked, this still returns false
  
    renderLoginButton() {
      const {user} = this.context;
      if (user) {
        const name = user.nickname;
        return &lt;Link to="/profile"&gt;Hey there {name}!&lt;/Link&gt;
      } else {
        return &lt;button onClick={this.showLock}&gt;Login&lt;/button&gt;
      }
    }
  
    render() {
      return (
        &lt;header&gt;
          {this.renderLoginButton()}
        &lt;/header&gt;
      );
    }
  }
  </code></pre>
  
  <p>I am following the official React docs about Context and updating it, found here: <a href="https://facebook.github.io/react/docs/context.html" rel="nofollow">https://facebook.github.io/react/docs/context.html</a></p>
  
  <p>As I said I know why this is not working: data can only be sent one way. But I need to find a way to make this work, and to be honest I think I've been staring at this too long and am now out of options and my brain is a bit frazzled.</p>