The question is more like : this.props vs this.state
Controlled components (or stateless components) :
Controlled components are designed to be use by an other components (also called 'containers') that manage props for them.
So :
- Pros :
- Very usefull when your app is embracing 'Flux' architecture. You can easily separate 'containers' and 'views'.
- You do not care about 'states' of the component as, the component's state is in the STORE ( cf. Flux ) and can focus only on props.
- As your components is stateless, you can see them like a Pure functions that just render your store. Thus you can test it, thus your app is more in 'predicatable state', thus your app is easily debuggable
- As your components is stateless, you can use PropTypes as a documentation for how to use your component.
- As your components is stateless, you just have to focus on your 'app state' and totally ignore components. THE BIG WIN is : you can totally describe your app as state transitions, ie, state1 -> render1, state2 -> render2, ... and you fall in : predictable app state === testable app === scalable app
- Cons :
- You have to describe your 'states' app. Its time consuming.
- You have to manage your store, dispatcher, and al. Fortunately we have redux, alt, MobX, ... Its time consuming (learning curves ...) .
- You have to think in Flux arch to have all the Pros. Its time consuming.
Uncontrolled components (or statefull components) :
Uncontrolled components are designed to be used everywhere.
Pros :
- Your component is app independant. Just use it like an instance of a class. With contructor, attributs and methods.
- Your component can be developed without any understanding of the app or of the architetcure. Thus, you can easily hire a freelancer to develop it.
Cons :
- How to test it ? Its hard. No predictable state.
- How to document it ? You have to describe public API (props/methodes) and private API (states). Its time consuming.
- How to share the component state ? With public API/ Methodes if the component let you this possibility. Its time consuming.
Conclusion :
Both of them can consuming your time in a heavy way if you choose the wrong 'paradigm'.
Ask you everytime the question :
If you do not have to share the component's state with an other component, go to Uncontrolled component and let it manage its own state :
If you have to know the state of the component, you have to control it ! Go to Controlled component :
- YourComponent.containers.jsx --> (talk to the store)
- YourComponent.view.jsx --> (just a render of props passed by the container)
Do not forget this : You can mix them together, but each time you will use an Uncontrolled Component, its a part of your app you cannot predict and test. So the question is : Do you care about testing your component ?