@msavin Hey dude!
I am so grateful for that forked song! I’ve heard it five months ago in the radio, in another country, and could not find the name. I rembered some parts (more or less correctly ), but were not able to find that song actually. I searched so much and now found it here at the forums, so much thanks. You the real MVP.
BTW: Mantra is long overdue. I hope that it will introduce the way to write our meteor applications - without struggling about the right architecture, libraries and technologies. I wait eagerly for Monday to see whether Mantra keeps its promises. Great work!
This is a great question, and something i’ve struggled with in the past. Using the autocomplete example… If you want to keep your view decoupled so that the input box, dropdown, etc… have no knowledge of your app (for re-usability), you can use this.state in the container and pass it down as props. You can create a function like updateDropdownStatus and pass that down as a prop as well. This works as long as you’re not passing it down too far, then it can get confusing as to where it originated from (then Redux is more simple in that case).
I just wanted to clarify this a bit, even though others have answered this as well.
First, I think it makes sense to look at why to do this in the first place:
**1. Easier mental model**
When the data changing happens somewhere else, it’s easier to think about what your view is doing. It can only have one paramater… props, so there are less possible variations of ‘what could have happened’ when debugging.
When the localstate / remote db fetching is in one place (a container) it makes it easier to pinpoint where data lives and how it might be triggered. In a package/component when all the state lives at the very top of it’s tree there are no doubts about where to look. In a large app, something like Redux means that all local state lives in one object tree.
When the actions (or verbs) are in once place… typically functions, you can also know where to jump to. For example if you are curious on how the data in props changed, you know to start with any functions the container provides… or if using Redux, what actions are imported for this.
Additionally with Redux if trapping a debugging in Actions is clear, you can always put a breakpoint in the reducer, which is simply a function that takes the old state and returns the new state… which should solve ‘how’ it got changed (via stacktraces).
**2. Easier testing**
If database calls and local state changes are somewhere else than that means you don’t have to stub out Meteor or other hard to test things. A component just using props is just like this first normal function:
// easy to test, no suprises
function addTwo(a, b) {
return a + b;
}
// hard to test, hidden surprise inside
function addTwo(a, b) {
Posts.update('id2', {$set: {time: Date.now()}})
return a + b;
}
3. Easier Re-Use
Most apps have very domain specific rules that only apply to this app. Perhaps it’s just something simple like triggering analytics or something complicated that determines what data to fetch. By isolating all of this into one place; anywhere really but a single view ‘container’ is good, and outside of the view altogether (like Redux) is even better (for re-use)!
For what it's worth some devs on React core have mentioned that they notice the need for Redux as leaky abstraction and are trying out ways to achieve the same thing without having to use Redux/flux.
This is really great @arunoda ! Thanks for setting up a standard architecture, I think this is very much needed and will greatly reduce the JS fatigue as we can now just go with one setup if maintainability is needed.
I’m sure you’ve thought of this but a file generator (perhaps Yo) would go a long way to init a basic app (sans training wheels) with wiring, and to scaffold out new pieces.
A set of Sublime snippets may also help add support and speedup development (I’ve found my Vim snippets have allowed me to use React+Redux and still beat the times it used to take to build in Blaze).
@arunoda It may to late for this, but have you checked on Cycle.js?. I think it’s already aimed to work as you intend to work with react (with a purely functional approach), cycle.js inputs are either props, events or components if I’m not wrong (I just bumped into cycle.js not too long ago).
Regardless of that, I think this is an awesome work, and is probably what this community needed! Great Job!
Yeah! Cycle is doing a great job. But Mantra is a completely different project.
Cycle introduce it’s own component system and so on. And even the DOM layer.
But we don’t. (And we don’t have resources either).
Mantra is a way to formalize on folder structure and where your code goes and so on.
Then, we’ll let some flexibility to choose whatever we want to use in the data layer.
(Still while following some rules)
And our intention is not to fix the JS fatigue problem, but just for Meteor.
Because Meteor solves a lot of JS fatigue issues.
Since Mantra will focus on using pure UI react components, what are your thoughts on utilizing packages already out there that may not conform to these standards? For example, https://github.com/callemall/material-ui has a ton of nice components built for react, but I their components are stateful. What do you suggest here? Wrap those components in containers? Rewrite them? Don’t use them?
There is no thing in Matra called “Pure UI components”, inside a component they can use any React component. (even containers build inside Mantra or stuff like meterial-ui)
What Mantra does is provide a way to create our app UI in a sensible way, while re-using as possible as we can.
Think of it this way. I have a tweet component that shows a list of tweets. If I want to reuse that component, I need to make a few containers to handle getting the right data context for say your tweet timeline, your mention timeline, and a search timeline. In the end, we are still displaying a tweet component and your reusability goes up. I think React naturally encourages that with it’s usage patterns vs Blaze, it is much harder to drive that out from the start of coding.
kk, sry for this stupid questions - i’m pretty new to meteor and just hoped to have a guideline for everything as long as the meteor guide isn’t for react
I just wanted to get started with testing in meteor and wondered why you aren’t using velocity in https://github.com/mantrajs/mantra-sample-blog-app - just a preference or is there some more reasoning?
I can’t speak for Arunoda, but my experience with velocity has been that it is not very stable when it comes to running meteor tests on Continuous Integration tools (like TravisCI).
I know Velocity team has a done a lot to make it’s awesome. But, now it’s in a very sad situation. (Many parts of it are not maintained now)
Velocity testing is very hard since you need to work with Meteor to run the test. In Mantra we handle this with unit-testing.
So, you don’t need to deal with Meteor to run tests. That’s a huge win.
We don’t work with E2E testing. For that, you can use some other standard projects to do E2E or something like Chimp.
No one should use Velocity for any new frameworks. It is only a peg-leg solution until Meteor 1.3 is released.
@arunoda, I’m also looking at doing exactly the same, to have the ability to run unit tests using standard tools for all modules, so I’m excited to see what you come up with.