Thanks for putting this together, always interesting to see people use React for the first time! I did a code review of sorts and cleaned up the code to be more idiomatic React. You can find the series of commits with in-depth comments on GitHub [1]. I may even write this up as a blog post on my website [2].<p>In short:<p>- Don't pass around components and call methods on them; prefer to pass props instead<p>- Conditional rendering instead of hiding, exactly as [3]<p>- Use the JSX harmony transforms<p>- Declare props<p>- Use classSet<p>- setState only needs to include props that change, rest stay the same<p>[1] <a href="https://github.com/ianobermiller/reactexperiment/commits/" rel="nofollow">https://github.com/ianobermiller/reactexperiment/commits/</a><p>[2] <a href="http://ianobermiller.com" rel="nofollow">http://ianobermiller.com</a><p>[3] <a href="https://news.ycombinator.com/item?id=8247422" rel="nofollow">https://news.ycombinator.com/item?id=8247422</a>
> I first tried to do this: [...] ...which actually worked, but generated a React error message about an unmounted component.<p>I suspect that you were doing something wrong that triggered this error. Unmounting components based on state is perfectly idiomatic React, and I do it all the time:<p><pre><code> {this.state.mode === 'map' && <Map/>}
</code></pre>
You pay for the added DOM work, of course, but this is usually negligible in my experience, especially in your case. You do have to make sure you follow the component lifecycle so that you don't try to use getDOMNode() or similar with a component that is not currently mounted.
I see some criticism here but I think it is worth pointing out this looks like a person learning to use a new technology and sharing their experience, which is great.<p>Sometimes that means using non-idiomatic constructs or just having some rough edges. Please be considerate.
I'm not particularly fond of the way React mixes presentation (returning nodes in render()) and logic. Particularly things like:<p><pre><code> var classes = _.reduce(["flipped","correct","wrong"],function(m,c){return m+(this.state[c]?c+" ":"");},"",this);
</code></pre>
seem very inelegant compared to say, Angular's ngClass, which does the same thing in a data-driven way. But, that's not to say Angular is free from template logic either.
There's now a follow-up to this post, walking through a refactor based on the comments given here and elsewhere. Thank you all for the feedback!<p><a href="https://news.ycombinator.com/item?id=8273026" rel="nofollow">https://news.ycombinator.com/item?id=8273026</a>