The 3 components (NewGif/Counter/Button) should be decoupled and not see each others in any way. They can't import stuff from each others. Ideally, in a JS based solutions, one could be able to publish each 3 components in separate NPM packages that don't depend on each others.
This is currently possible because Components only expose public interface
The aim of decoupling the components is that a team can take ownership of each component. Then another team is responsible of making all the components work nicely together, and you already have split the work into 4 teams.
I actually worked like this, I've built 3 independent components which are isolated:
GifViewer
Button
Counter
I just kept in mind the public interface which is necessary to implement the business rule. That's why:
Button exposes isActive function
Counter exposes incrementByTwo and increment functions
So that all the component specific logic is encapsulated.
I've utilized Custom Matcher implementation (redux-elm allows you to build your own Matcher) to fetch all NewGif actions. If I wanted to keep it formally correct, I'd expose the Action string from GifViewer component so that I don't need to know internal details of GifViewer (I didn't do that tho, using just string)
For example, the NewGif component should not be aware of the presence of the existence of a counter, deeply hidden in a little stats popup of our app. If this counter had to be removed by the business, it's place in dom tree updated, or it's business rule be changed, the team maintaining the NewGif widget should rather not have to know about that.
Each component does not know anything about their parent. Didn't need to change single line of code in GifViewer to implement the business rule.
It should also be easy to move the position of components. For example imagine the button is top left of your app, and the business now wants it inside a popup, bottom right: this move of component in the tree should rather be easy to make (ie without having to modify all parent components, for example).
endsWithMatcher does the magic, I can move around components however I want, yet everything will still be working.
This is currently possible because Components only expose public interface
I actually worked like this, I've built 3 independent components which are isolated:
I just kept in mind the public interface which is necessary to implement the business rule. That's why:
Button
exposesisActive
functionCounter
exposesincrementByTwo
andincrement
functionsSo that all the component specific logic is encapsulated.
The business rule then looks like this:
I've utilized Custom Matcher implementation (redux-elm allows you to build your own Matcher) to fetch all
NewGif
actions. If I wanted to keep it formally correct, I'd expose the Action string fromGifViewer
component so that I don't need to know internal details ofGifViewer
(I didn't do that tho, using just string)Each component does not know anything about their parent. Didn't need to change single line of code in
GifViewer
to implement the business rule.endsWithMatcher
does the magic, I can move around components however I want, yet everything will still be working.