I've got a React component with an input, and an optional "advanced input":
[ basic ]
Hide Advanced...
[ advanced ]
The advanced on the bottom goes away if you click "Hide Advanced", which changes to "Show Advanced". That's straightforward and working fine, there's a showAdvanced key in the state that controls the text and whether the advanced input is rendered.
External JS code, however, might change the value of advanced, in which case I want to show the [advanced] input if it's currently hidden and the value is different than the default. The user should be able to click "Hide Advanced" to close it again, however.
So, someone external calls cmp.setState({advanced: "20"}), and I want to then show advanced; The most straightforward thing to do would just be to update showAdvanced in my state. However, there doesn't seem to be a way to update some state in response to other state changes in React. I can think of a number of workarounds with slightly different behavior, but I really want to have this specific behavior.
Should I move showAdvanced to props, would that make sense? Can you change props in response to state changes? Thanks.
Okay first up, you mention that a third party outside of your component might call cmp.setState()? This is a huge react no-no. A component should only ever call it's own setState function - nothing outside should access it.
Also another thing to remember is that if you're trying change state again in response to a state change - that means you're doing something wrong.
When you build things in this way it makes your problem much harder than it needs to be. The reason being that if you accept that nothing external can set the state of your component - then basically the only option you have is to allow external things to update your component's props - and then react to them inside your component. This simplifies the problem.
So for example you should look at having whatever external things that used to be calling cmp.setState() instead call React.renderComponent on your component again, giving a new prop or prop value, such as showAdvanced set to true. Your component can then react to this in componentWillReceiveProps and set it's state accordingly. Here's an example bit of code:
var MyComponent = React.createClass({
getInitialState: function() {
return {
showAdvanced: this.props.showAdvanced || false
}
},
componentWillReceiveProps: function(nextProps) {
if (typeof nextProps.showAdvanced === 'boolean') {
this.setState({
showAdvanced: nextProps.showAdvanced
})
}
},
toggleAdvancedClickHandler: function(e) {
this.setState({
showAdvanced: !this.state.showAdvanced
})
},
render: function() {
return (
<div>
<div>Basic stuff</div>
<div>
<button onClick={this.toggleAdvancedClickHandler}>
{(this.state.showAdvanced ? 'Hide' : 'Show') + ' Advanced'}
</button>
</div>
<div style={{display: this.state.showAdvanced ? 'block' : 'none'}}>
Advanced Stuff
</div>
</div>
);
}
});
So the first time you call React.renderComponent(MyComponent({}), elem) the component will mount and the advanced div will be hidden. If you click on the button inside the component, it will toggle and show. If you need to force the component to show the advanced div from outside the component simply call render again like so: React.renderComponent(MyComponent({showAdvanced: true}), elem) and it will show it, regardless of internal state. Likewise if you wanted to hide it from outside, simply call it with showAdvanced: false.
Added bonus to the above code example is that calling setState inside of componentWillReceiveProps does not cause another render cycle, as it catches and changes the state BEFORE render is called. Have a look at the docs here for more info: http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops
Don't forget that calling renderComponent again on an already mounted component doesn't mount it again, it just tells react to update the component's props and react will then make the changes, run the lifecycle and render functions of the component and do it's dom diffing magic.
Revised answer in comment below.
My initial wrong answer:
The lifecycle function componentWillUpdate will be ran when new state or props are received. You can find documentation on it here: http://facebook.github.io/react/docs/component-specs.html#updating-componentwillupdate
If, when the external setState is called, you then set showAdvanced to true in componentWillUpdate, you should get the desired result.
EDIT: Another option would be to have the external call to setState include showAdvanced: true in its new state.
Related
Does React re-render all components and sub components every time setState() is called?
If so, why? I thought the idea was that React only rendered as little as needed - when state changed.
In the following simple example, both classes render again when the text is clicked, despite the fact that the state doesn't change on subsequent clicks, as the onClick handler always sets the state to the same value:
this.setState({'test':'me'});
I would've expected that renders would only happen if state data had changed.
Here's the code of the example, as a JS Fiddle, and embedded snippet:
var TimeInChild = React.createClass({
render: function() {
var t = new Date().getTime();
return (
<p>Time in child:{t}</p>
);
}
});
var Main = React.createClass({
onTest: function() {
this.setState({'test':'me'});
},
render: function() {
var currentTime = new Date().getTime();
return (
<div onClick={this.onTest}>
<p>Time in main:{currentTime}</p>
<p>Click me to update time</p>
<TimeInChild/>
</div>
);
}
});
ReactDOM.render(<Main/>, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
Does React re-render all components and sub-components every time setState is called?
By default - yes.
There is a method boolean shouldComponentUpdate(object nextProps, object nextState), each component has this method and it's responsible to determine "should component update (run render function)?" every time you change state or pass new props from parent component.
You can write your own implementation of shouldComponentUpdate method for your component, but default implementation always returns true - meaning always re-run render function.
Quote from official docs http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
By default, shouldComponentUpdate always returns true to prevent
subtle bugs when the state is mutated in place, but if you are careful to
always treat the state as immutable and to read-only from props and state
in render() then you can override shouldComponentUpdate with an
implementation that compares the old props and state to their
replacements.
Next part of your question:
If so, why? I thought the idea was that React only rendered as little as needed - when the state changed.
There are two steps of what we may call "render":
Virtual DOM renders: when render method is called it returns a new virtual dom structure of the component. As I mentioned before, this render method is called always when you call setState(), because shouldComponentUpdate always returns true by default. So, by default, there is no optimization here in React.
Native DOM renders: React changes real DOM nodes in your browser only if they were changed in the Virtual DOM and as little as needed - this is that great React's feature which optimizes real DOM mutation and makes React fast.
No, React doesn't render everything when the state changes.
Whenever a component is dirty (its state changed), that component and its children are re-rendered. This, to some extent, is to re-render as little as possible. The only time when render isn't called is when some branch is moved to another root, where theoretically we don't need to re-render anything. In your example, TimeInChild is a child component of Main, so it also gets re-rendered when the state of Main changes.
React doesn't compare state data. When setState is called, it marks the component as dirty (which means it needs to be re-rendered). The important thing to note is that although render method of the component is called, the real DOM is only updated if the output is different from the current DOM tree (a.k.a diffing between the Virtual DOM tree and document's DOM tree). In your example, even though the state data hasn't changed, the time of last change did, making Virtual DOM different from the document's DOM, hence why the HTML is updated.
Yes. It calls the render() method every time we call setState only except when shouldComponentUpdate returns false.
Even though it's stated in many of the other answers here, the component should either:
implement shouldComponentUpdate to render only when state or properties change
switch to extending a PureComponent, which already implements a shouldComponentUpdate method internally for shallow comparisons.
Here's an example that uses shouldComponentUpdate, which works only for this simple use case and demonstration purposes. When this is used, the component no longer re-renders itself on each click, and is rendered when first displayed, and after it's been clicked once.
var TimeInChild = React.createClass({
render: function() {
var t = new Date().getTime();
return (
<p>Time in child:{t}</p>
);
}
});
var Main = React.createClass({
onTest: function() {
this.setState({'test':'me'});
},
shouldComponentUpdate: function(nextProps, nextState) {
if (this.state == null)
return true;
if (this.state.test == nextState.test)
return false;
return true;
},
render: function() {
var currentTime = new Date().getTime();
return (
<div onClick={this.onTest}>
<p>Time in main:{currentTime}</p>
<p>Click me to update time</p>
<TimeInChild/>
</div>
);
}
});
ReactDOM.render(<Main/>, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
It seems that the accepted answers are no longer the case when using React hooks (with primitive values, see comments on this answer for details). You can see in this code sandbox that the class component is rerendered when the state is set to the same value, while in the function component, setting the state to the same value doesn't cause a rerender.
https://codesandbox.io/s/still-wave-wouk2?file=/src/App.js
React 18 and beyond
Starting from React 18 all state updates are automatically batched. In this way, React groups multiple state updates into a single re-render for better performance.
So when you update your state, React always try to batch these updates in a group update, causing fewer render than setState calls. The behaviour is the same when using hooks.
You can read the very long explanation in the Automatic batching for React 18 announcement.
React 17 and below
In React 17 and below, only updates inside React event handlers are batched. Updates triggered from promises, setTimeout, native event handlers, or other events are not batched in React by default.
Another reason for "lost update" can be the next:
If the static getDerivedStateFromProps is defined then it is rerun in every update process according to official documentation https://reactjs.org/docs/react-component.html#updating.
so if that state value comes from props at the beginning it is overwrite in every update.
If it is the problem then U can avoid setting the state during update, you should check the state parameter value like this
static getDerivedStateFromProps(props: TimeCorrectionProps, state: TimeCorrectionState): TimeCorrectionState {
return state ? state : {disable: false, timeCorrection: props.timeCorrection};
}
Another solution is add a initialized property to state, and set it up in the first time (if the state is initialized to non null value.)
Not All Components.
the state in component looks like the source of the waterfall of state of the whole APP.
So the change happens from where the setState called. The tree of renders then get called from there. If you've used pure component, the render will be skipped.
Regardless of the well explained answers here, there may be other reasons why you don't see the change you expect post changing the props or state:
Watch out for any event.preventDefault(); in the code where you want to re-render by a state \ props change, as it will cancel any cancelable event following this statement.
You could use setState() only after comparing the current state value and the new one and they are different.
I know that I will ask a question that brake some rules about the core/basic way to use React... but maybe with this example, someone helps me to solve the problem that I facing.
This is not the full code of my project, but show exactly the idea of my problem:
https://codesandbox.io/s/change-state-from-external-component-zi79e
The thing is I need to change a state from a child component from the parent component, but I don't want to run a render method in my parent or handle the state in the parent component.
Exists a way to achieve this? In my project, I have a parent that creates multiple generic children and it will be more difficult to handle this request.
And specifically, I need to change the state of one child (MyFirstChild), after another child (SecondChild) read the keystroke and run an API to get some values from my backend; after that, I need to send the change to "MyFirstChild" to change his state.
The parent component has ~50 child components and I blocked the re-render method (With the method shouldComponentUpdate)
The expected answer is: "It's not possible, or, you broke the good use of React"...
But, maybe using forwardRef or ref, or something else that I not see can help me to work around this...
To change the state of a child component from the parent without having to run a render method (in the parent): one possible solution would be to use Redux. With Redux from the parent you can dispatch an Action (execute an Action that changes the state of Redux).
And in the child component, you receive that part of the state that you change (it could be a string, object, etc) as a prop. So when it is changed from the parent, your child component will render again without having to run a render method in the parent.
https://react-redux.js.org/introduction/basic-tutorial
You could also use Context for the same purpose.
However, I saw your code example, I am not sure the exact reason of why you don't want to make a render in the parent, but the easiest solution for what you need would be to send the function that you want to execute in the parent as a prop and also the title.
If you want to change things from the parent, without re-rendering again with Redux, it would be something like this:
In the parent
const changeTitle = (newTitle) => {
this.props.setTitle(newTitle);
}
return (
<div className="App">
<ChildComponent />
</div>
);
const mapDispatchToProps = dispatch => ({
setTitle: newTitle => dispatch(setTitleACTION(newTitle)),
});
In the child
return (
<div>
<h1>
{this.props.title}
</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
const mapStateToProps = ({ title }) => ({
title,
});
export default connect(mapStateToProps, null)(ChildComponent);
Again if you make this with Redux, you can get the "title" prop from the Redux store, and in the parent, you will change that variable (calling to a Redux action) without rendering the parent again.
If you want to fire the event from the child component, you can dispatch the action from the child component or you could call a function (that you receive from props from the parent) and call that function whenever you need.
Can't we use props here for passing data instead of trying to manipulate state from outside of component?
Based on #david paley explanation...
If the only way to achieve this is using Redux, I post my solution (It's the same example, but, implementing Redux)... hope that works for anyone else.
https://codesandbox.io/s/change-state-from-external-component-redux-rmzes?file=/src/App.js
Does React re-render all components and sub components every time setState() is called?
If so, why? I thought the idea was that React only rendered as little as needed - when state changed.
In the following simple example, both classes render again when the text is clicked, despite the fact that the state doesn't change on subsequent clicks, as the onClick handler always sets the state to the same value:
this.setState({'test':'me'});
I would've expected that renders would only happen if state data had changed.
Here's the code of the example, as a JS Fiddle, and embedded snippet:
var TimeInChild = React.createClass({
render: function() {
var t = new Date().getTime();
return (
<p>Time in child:{t}</p>
);
}
});
var Main = React.createClass({
onTest: function() {
this.setState({'test':'me'});
},
render: function() {
var currentTime = new Date().getTime();
return (
<div onClick={this.onTest}>
<p>Time in main:{currentTime}</p>
<p>Click me to update time</p>
<TimeInChild/>
</div>
);
}
});
ReactDOM.render(<Main/>, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
Does React re-render all components and sub-components every time setState is called?
By default - yes.
There is a method boolean shouldComponentUpdate(object nextProps, object nextState), each component has this method and it's responsible to determine "should component update (run render function)?" every time you change state or pass new props from parent component.
You can write your own implementation of shouldComponentUpdate method for your component, but default implementation always returns true - meaning always re-run render function.
Quote from official docs http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
By default, shouldComponentUpdate always returns true to prevent
subtle bugs when the state is mutated in place, but if you are careful to
always treat the state as immutable and to read-only from props and state
in render() then you can override shouldComponentUpdate with an
implementation that compares the old props and state to their
replacements.
Next part of your question:
If so, why? I thought the idea was that React only rendered as little as needed - when the state changed.
There are two steps of what we may call "render":
Virtual DOM renders: when render method is called it returns a new virtual dom structure of the component. As I mentioned before, this render method is called always when you call setState(), because shouldComponentUpdate always returns true by default. So, by default, there is no optimization here in React.
Native DOM renders: React changes real DOM nodes in your browser only if they were changed in the Virtual DOM and as little as needed - this is that great React's feature which optimizes real DOM mutation and makes React fast.
No, React doesn't render everything when the state changes.
Whenever a component is dirty (its state changed), that component and its children are re-rendered. This, to some extent, is to re-render as little as possible. The only time when render isn't called is when some branch is moved to another root, where theoretically we don't need to re-render anything. In your example, TimeInChild is a child component of Main, so it also gets re-rendered when the state of Main changes.
React doesn't compare state data. When setState is called, it marks the component as dirty (which means it needs to be re-rendered). The important thing to note is that although render method of the component is called, the real DOM is only updated if the output is different from the current DOM tree (a.k.a diffing between the Virtual DOM tree and document's DOM tree). In your example, even though the state data hasn't changed, the time of last change did, making Virtual DOM different from the document's DOM, hence why the HTML is updated.
Yes. It calls the render() method every time we call setState only except when shouldComponentUpdate returns false.
Even though it's stated in many of the other answers here, the component should either:
implement shouldComponentUpdate to render only when state or properties change
switch to extending a PureComponent, which already implements a shouldComponentUpdate method internally for shallow comparisons.
Here's an example that uses shouldComponentUpdate, which works only for this simple use case and demonstration purposes. When this is used, the component no longer re-renders itself on each click, and is rendered when first displayed, and after it's been clicked once.
var TimeInChild = React.createClass({
render: function() {
var t = new Date().getTime();
return (
<p>Time in child:{t}</p>
);
}
});
var Main = React.createClass({
onTest: function() {
this.setState({'test':'me'});
},
shouldComponentUpdate: function(nextProps, nextState) {
if (this.state == null)
return true;
if (this.state.test == nextState.test)
return false;
return true;
},
render: function() {
var currentTime = new Date().getTime();
return (
<div onClick={this.onTest}>
<p>Time in main:{currentTime}</p>
<p>Click me to update time</p>
<TimeInChild/>
</div>
);
}
});
ReactDOM.render(<Main/>, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
It seems that the accepted answers are no longer the case when using React hooks (with primitive values, see comments on this answer for details). You can see in this code sandbox that the class component is rerendered when the state is set to the same value, while in the function component, setting the state to the same value doesn't cause a rerender.
https://codesandbox.io/s/still-wave-wouk2?file=/src/App.js
React 18 and beyond
Starting from React 18 all state updates are automatically batched. In this way, React groups multiple state updates into a single re-render for better performance.
So when you update your state, React always try to batch these updates in a group update, causing fewer render than setState calls. The behaviour is the same when using hooks.
You can read the very long explanation in the Automatic batching for React 18 announcement.
React 17 and below
In React 17 and below, only updates inside React event handlers are batched. Updates triggered from promises, setTimeout, native event handlers, or other events are not batched in React by default.
Another reason for "lost update" can be the next:
If the static getDerivedStateFromProps is defined then it is rerun in every update process according to official documentation https://reactjs.org/docs/react-component.html#updating.
so if that state value comes from props at the beginning it is overwrite in every update.
If it is the problem then U can avoid setting the state during update, you should check the state parameter value like this
static getDerivedStateFromProps(props: TimeCorrectionProps, state: TimeCorrectionState): TimeCorrectionState {
return state ? state : {disable: false, timeCorrection: props.timeCorrection};
}
Another solution is add a initialized property to state, and set it up in the first time (if the state is initialized to non null value.)
Not All Components.
the state in component looks like the source of the waterfall of state of the whole APP.
So the change happens from where the setState called. The tree of renders then get called from there. If you've used pure component, the render will be skipped.
Regardless of the well explained answers here, there may be other reasons why you don't see the change you expect post changing the props or state:
Watch out for any event.preventDefault(); in the code where you want to re-render by a state \ props change, as it will cancel any cancelable event following this statement.
You could use setState() only after comparing the current state value and the new one and they are different.
I'm new to React and am trying to update the state of a parent component from the child everytime an onChange action happens. The onchange action comes from an input box that when letters are typed it updates the state of searchInputVal with the value of what has been typed. I have a parent <App/> component with the following properties and states here:
updateSampleFilteredState(filteredSamples) {
this.setState({
samples: filteredSamples
});
},
getInitialState () {
return {
samples:allSamples,
searchInputVal:""
}}
I pass the properties and states down to a child component here:
updateNewSampleState(filteredSamples){
return (
this.props.updateSampleFilteredState(filteredSamples)
)
}
render() {
const filteredSamples = this.props.samples.filter(sample => {
return sample.sampleFamily.toLowerCase().indexOf(this.props.searchInputVal.toLowerCase()) !== -1;
});
this.updateNewSampleState(filteredSamples);
return <div className="samples-container-inner-styling">
{
filteredSamples.map((sample) => {
return (...
Before I added the line this.updateNewSampleState(filteredSamples); the child component would render out the filtering just fine but obviously not update the state of sample with the new filtered state. When I the line this.updateNewSampleState(filteredSamples); to execute the function in the component to set the new state I get a list of re-occuring errors that eventually make my app crash. The errors say something about an anti pattern. I'm not sure how else to update the state?
You should't be updating the state from the render function, and you are facing the reason why that's a bad way to do things. Every time you call the setState the component re-renders, so if you call it inside the render function it will be called again and so on... You should ask yourself why are you calling that function there. I guess you could just do it in the onChange function you are using for the input.
As already mentioned by #César, setting the state in the renderer doesn't make sense, since setting the state triggers a rerender of the component, so you basically get something like an infinite render loop.
Given that you are computing filteredSamples only from the props, you could compute that state in the constructor:
The constructor is the right place to initialize state.
However, note the following when deriving state from props in the constructor:
It's okay to initialize state based on props if you know what you're doing. [...]
Beware of this pattern, as it effectively "forks" the props and can lead to bugs. Instead of syncing props to state, you often want to lift the state up.
If you "fork" props by using them for state, you might also want to implement componentWillReceiveProps(nextProps) to keep the state up-to-date with them. But lifting state up is often easier and less bug-prone.
Say in my first file, open.jsx, I have:
// Default Import Statements here
var open = React.createClass({
render() {
return (
<div>
<Dialog
title="Test"
ref="openDialog">
</Dialog>
</div>
);
},
_handleTouchTap() {
this.refs.openDialog.setState({open:true});
}
});
module.exports = open;
And in my app.jsx file I have:
const testComponent = React.createClass({
render() {
return (
<FlatButton label="Test" onTouchTap={this._handleTouchTap}/>
);
},
_handleTouchTap: function() {
Open._handleTouchTap();
}
});
module.exports = testComponent;
The error I am getting currently is:
Uncaught TypeError: Open._handleTouchTap is not a function
Does anyone know how I can pass methods in between files for React?
I want to call open.jsx's _handleTouchTap() method when they press the button in app.jsx.
When you call Open._handleTouchTap, you are attempting to call the method as if it was static, on the Open class. This method, however, is only available once an Open component has been instantiated. You must attach a ref to the component and call the method via this.refs.someOpenComponent._handleTouchTap().
You may want to provide more of your code so better examples can be provided.
Also, methods with an underscore in front of their names typically denote "private" methods, and should not be called from a different class. You may want to consider renaming this function so it is more clear what its purpose is.
I'm assuming you want to render some page with a button, and show the dialog as soon as someone presses the FlatButton. I also notice you're using material-ui, so let's go with that.
When starting any React project, it's a good idea to think about your component hierarchy. Because you're using material-ui and the Dialog component's opening is controlled by passing props, it's easiest to use the following approach.
Simple case
Use a root component App (in app.jsx), which mounts a button and mounts a dialog, but the dialog is initially in a hidden state (the "open" prop on Dialog defaults to false) so doesn't visually show up yet (even though it is mounted). In this case, you will want the button to set the open prop on Dialog to true as soon as the button is pressed.
Please note I would recommend separating most of this rendering stuff into separate components; for illustration purposes, let's keep everything in App.jsx.
The way you want to organise in this case is as follows:
// App.jsx (render + handle click function only)
render: function() {
return (
<div>
<FlatButton label="Test" onTouchTap={this._handleTapTestButton}/>
<Dialog
title="Test"
open={this.state.dialogOpen}>
<div>My dialog contents</div>
</Dialog>
</div>
);
},
_handleTapTestButton: function() {
this.setState({dialogOpen: !this.state.dialogOpen}); // flip the state
}
See? No refs needed even (and that's good!). Now, this works fine if your Dialog component is located nice and close to your FlatButton.
More complex case: Dialog is far away from FlatButton
Your next question might be "how can I organise this when the Dialog component is nested somewhere deep inside a totally different component that is not a child or parent of the App.jsx component", but instead a sibling?
Well, this smells a little to me (just an opinion). It's not an anti-pattern per sé, but if you can avoid this, I would recommend you do. Ie: for your own convenience and for maintainability's sake, try to keep components that naturally interact with each other close (in terms of parent-child) to each other in the component hierarchy. This way, you can communicate pretty easily using props (see React's info on this. That's definitely not an absolute rule though, there are plenty of reasons to deviate from that.
Let's assume you have a valid case for not doing that, and even worse: the component are siblings, not direct or indirect grandparent/parent/child.
In that case, you have two options:
Use a store and associated events (or any other javascript code that communicates state) to communicate the state change to the other component (ie using Flux, Redux, or whatever you prefer). In this case, when the button is clicked, you fire an event somewhere that gets picked up by the other component. This event triggers a state change in the other component. Warning: this can get unmanageable pretty quickly, which is one of the reasons state-managing-frameworks like Flux and Redux exist.
OR, onTouchTap, have the FlatButton call a function that was passed down from a shared parent component. This function then flips the state at the shared parent component, and passes this state as props to the Dialog. Ie, when both components share a grandparent somewhere, you can define a function at the grandparent level and pass that function as a prop down to the FlatButton. The function's role is to change the state at the grandparent (dialogOpen). This state is then passed down one or more components as a prop all the way down the hierarchy until it ends up at the Dialog, which will auto show itself as the prop switches to true.
There are serious advantages/disadvantages to either approach. The first approach leaks your UI rendering logic into your stores (which is usually inevitable anyway, but can be managed using things like Flux), the second leaks it into the component hierarchy (tricky for maintainability) and tends to create tight coupling (yuck).