I started using ParseReact (https://github.com/ParsePlatform/ParseReact), but i want to know if there are any way of realtime data ? Like in MeteorJS or Firebase.
To add Parse data to a component, it simply needs to subscribe to a standard Parse Query. This is done through an implementation of the newly-proposed observe() API for React. The ParseReact Mixin allows a version of this new lifecycle method to be used today with Parse Queries.
If you're using React with ES6 classes, we also provide a subclass of React.Component that allows you to use the observe() and Query-specific APIs.
var CommentBlock = React.createClass({
mixins: [ParseReact.Mixin], // Enable query subscriptions
observe: function() {
// Subscribe to all Comment objects, ordered by creation date
// The results will be available at this.data.comments
return {
comments: (new Parse.Query('Comment')).ascending('createdAt')
};
},
render: function() {
// Render the text of each comment as a list item
return (
<ul>
{this.data.comments.map(function(c) {
return <li>{c.text}</li>;
})}
</ul>
);
}
});
Whenever this component mounts, it will issue the query and the results will be attached to this.data.comments. Each time the query is re-issued, or objects are modified locally that match the query, it will update itself to reflect these changes.
Mutations are dispatched in the manner of Flux Actions, allowing updates to be synchronized between many different components without requiring views to talk to each other. All of the standard Parse data mutations are supported, and you can read more about them in the Data Mutation guide.
// Create a new Comment object with some initial data
ParseReact.Mutation.Create('Comment', {
text: 'Parse <3 React'
}).dispatch();
I tried the example, but always have to reload view. It`s not the same as Firebase and MeteorJS
I would also like to hear more about this...Not sure if this is actually a supported feature or not. As the documentation states, Queries you are subscribed to in the observe function will be updated with new props/state, as well as any time a Mutation occurs. In this sense it is very much like Meteor in that changes changes to state (much like changes to Session variables) can reload queries to the backend.
Where it differs is that, unlike Meteor, changes in Parse (say, directly in the db or from another front-end instance) are not communicated to all subscribed React front-ends. At least as far as I can tell. Which is kinda disappointing. Would love to hear from someone more experienced, who hasn't just been messing with ParseReact for the past 24 hours.
Related
I am using react-apollo and have been for quite some time. One thing that has already been a problem for me is the fact that refetch doesn't work when using a mutation This has been a know issue for as long as I have been using the app.
I have got round this by using the refetch prop that is available on a query.
<Query query={query} fetchPolicy={fetchPolicy} {...props}>
{({ loading, data, error, refetch }) => {
... pass down to mutation
</Query>
However I am now reading in the documentation that you recieve
an update method as part of a mutation and you should use this to update your application after a mutation.
Can you use the update function to update your UI's data and have it update after finishing a mutation? If you can, is this the standard way to do updates now?
*Using refetchQueries not working
As you can see in the image the console.info() displays that the data.status = "CREATED"; but the request coming back from the mutation directly is data.status = "PICKED"; PICKED is the correct and uptodate information in the DB.
In order of preference, your options are:
Do nothing. For regular updates to an individual node, as long as the mutation returns the mutated result, Apollo will update the cache automatically for you. When this fails to work as expected, it's usually because the query is missing the id (or _id) field. When an id field is not available, a custom dataIdFromObject function should be provided to the InMemoryCache constructor. Automatic cache updates also fail when people set the addTypename option to false.
Use update. The update function will run after your mutation completes, and lets you manipulate the cache directly. This is necessary if the mutation affects a field returning a list of nodes. Unlike simple updates, Apollo has no way to infer whether the list should be updated (and how) following the mutation, so we have to directly update the cache ourselves. This is typically necessary following create and delete mutations, but may also be needed after an update mutation if the updated node should be added or removed to some field that returns a list. The docs go into a good deal of detail explaining how to do this.
<Mutation
mutation={ADD_TODO}
update={(cache, { data: { addTodo } }) => {
const { todos } = cache.readQuery({ query: GET_TODOS });
cache.writeQuery({
query: GET_TODOS,
data: { todos: todos.concat([addTodo]) },
});
}}
>
{(addTodo) =>(...)}
</Mutation>
Use refetchQueries. Instead of updating the cache, you may also provide a refetchQueries function, which should return an array of objects representing the queries to refetch. This is generally less desirable than using update since it requires one or more additional calls to the server. However, it may be necessary if the mutation does not return enough information to correctly update the cache manually. NOTE: The returned array may also be an array of strings representing operation names, though this is not well documented.
<Mutation
mutation={ADD_TODO}
refetchQueries={() => [
{ query: TODOS_QUERY, variables: { foo: 'BAR' } },
]}
>
{(addTodo) =>(...)}
</Mutation>
Use refetch. As you already showed in your question, it's possible to use the refetch function provided by a Query component inside your Mutation component to refetch that specific query. This is fine if your Mutation component is already nested inside the Query component, but generally using refetchQueries will be a cleaner solution, particularly if multiple queries need to be refetched.
Use updateQueries. This is a legacy option that's no longer well-documented, but provided similar functionality to update before update was added. It should not be used as it may be deprecated in the future.
UPDATE:
You may also set up your schema in such a way that queries can be refetched as part of your mutation. See this article for more details.
I have a simple app which pulls products from an API and displays them on-page, like this:
I've added Vuex to the app so that the search results as well as the product search array doesn't disappear when the router moves the user to a specific product page.
The search itself consists of the following steps:
show loading spinner (update the store object)
dispatch an action to access the API
update the store object with products, spinner
decide if the product list is exhausted
hide loading spinner
You get the idea.
With all of the variables stored in Vuex, it stands to reason all of the business logic should belong there as well, but should it really?
I'm talking specifically about accessing store params such as productsExhausted (when there are no more products to display) or productPage (which increments every time the infinite scroller module is triggered) etc.
How much logic - and what kind - belongs in Vuex? How much does not?
I was under the impression that Vuex is used for storage only but since all of the data is located there, fetching it all back to the Vue app only to send it all back seems like an overly verbose way to address the problem.
Vuex allows you to share data !
For everything that concerns the state of the app its pretty straightforward.
All the data that can be used by multiple components should be added
to the store.
Now concerning the business logic, even though I find its not really clear in the official documentation, it should follow the same principle.
What I mean is that logic that can be used by multiple components should be stored in actions.
Moreover actions allows you to deal with async operations. Knowing this, your code that pulls the data should definitely be stored in vuex's actions.
What I think you should do is to put the request inside an action, then mutate the state of your variables and automatically your UI will reflect the changes.
Moreover, a good pattern to apply is to convert most of the logic to a state logic. For instance consider this demo of a jumping snowman. In here the click action results on updating a value from the store. Although the interesting part is that one component uses the watch functionnality to be notified when the store changes. This way we keep the logic inside the component but use the store as an event emitter.
var store = new Vuex.Store({
state: {
isJumping: 0
},
mutations: {
jump: function(state){
state.isJumping++;
}
}
})
Vue.component('snowman', {
template: '<div id="snowman" :class="color">⛄</div>',
computed: {
isJumping: function(){
return this.$store.state.isJumping;
}
},
watch: {
isJumping: function(){
var tl = new TimelineMax();
tl.set(this.$el,{'top':'100px'})
tl.to(this.$el, 0.2, {'top':'50px'});
tl.to(this.$el, 0.5, {'top':'100px', ease: Bounce.easeOut});
}
}
})
I am kind of confused here on where to place my global functions. In a lot of examples a main.js file points to an app component and this is placed somewhere within the html. This workflow would be fine for me If I were to simply contain all my logic within this app component. But I am combining components with Laravel functionality so this does not work for me.
Currently my main.js file contains a bunch of methods that I need to have access from anywhere in my app. These methods don't contain any broadcasting events so they can effectively be placed anywhere as long as they get a vue-resource instance.
My main.js file:
https://github.com/stephan-v/BeerQuest/blob/develop/resources/assets/js/main.js
Hopefully somebody can tell me where I could place my friendship methods if I were to use vuex or in general since this does not seem like best practice at all.
Thank you.
Vuex manages all of the data in your application. It's a "single source of truth" for data on your front-end. Therefore, anything that changes the state of your application, such as adding a friend, or denying a friend, needs to flow through Vuex. This happens through three main function types, getters, actions, and mutations.
Check out: https://github.com/vuejs/vuex/tree/master/examples/shopping-cart/vuex
Getters are used to fetch data from storage in Vuex. They are reactive to changes, meaning if Vuex data changes, the information in your component is updated as well. You can put these in something like getters.js so that you can import them in any module you need them in.
Actions are functions that you call directly, ie. acceptFriendRequest when a user clicks the button. They interact with your database, and then dispatch mutations. In this app, all of the actions are in actions.js.
So you'd call this.acceptFriendRequest(recipient) in your component. This would tell your database to update the friend status, then you get a confirmation back that this happened. That's when you dispatch a mutation that updates the current users' list of friends within Vuex.
A mutation updates the data in Vuex to reflect the new state. When this happens, any data you are retrieving in a getter is updated as well. Here is an example of the entire flow:
import {addFriend} from './actions.js';
import {friends} from './getters.js';
new Vue({
vuex:{
getters:{
friends
}
},
methods:{
addFriend
}
}
store.js:
export default {
state:{
friends: []
},
mutations:{
ADD_FRIEND(state, friend) {
state.friends.push(friend);
}
}
}
actions.js:
export default {
addFriend(friend){
Vue.http.post('/users/1/friends',friend)
.then((response)=>{
dispatch("ADD_FRIEND", response) //response is the new friend
})
}
}
getters.js
export default {
friends(state) {
return state.friends;
}
}
So all of these are organized into their own files, and you can import them in any component you need. You can call this.addFriend(friend) from any component, and then your getter which is accessed from this.friends will automatically update with the new friend when the mutation happens. You can always use the same data in any view in your app and know that it is current with your database.
Some misc stuff:
getters automatically receive state as a variable, so you can always reference the state of your Vuex store
mutations should never be asynchronous. Do fetching/updating in actions and then dispatch mutations just to update your data
creating services (or resources) using Vue Resource will make fetching/updating/deleting resources even easier. you can put these in separate files and import them in your actions.js to keep the database retrieval logic separated. Then you'd be writing something like FriendService.get({id: 1}) instead of Vue.http.get('/users/1'). see https://github.com/vuejs/vue-resource/blob/master/docs/resource.md
Vuex works with vue devtools for "time-traveling". You can see a list of every mutation that has taken place and rewind them/redo them. It's great for debugging and seeing where data is being changed.
I have been writing components in React.js recently. I have never had to use methods like componentWillMount and componentDidMount.
render is indispensable. getInitialState and other helper methods I wrote also come in handy. But not the two aforementioned lifecycle methods.
My current guess is that they are used for debugging? I can console.log out inside them:
componentWillMount: function() {
console.log('component currently mounting');
},
componentDidMount: function() {
console.log('component has mounted');
}
Are there any other uses?
componentDidMount is useful if you want to use some non-React JavaScript plugins. For example, there is a lack of a good date picker in React. Pickaday is beautiful and it just plain works out of the box. So my DateRangeInput component is now using Pickaday for the start and end date input and I hooked it up like so:
componentDidMount: function() {
new Pikaday({
field: React.findDOMNode(this.refs.start),
format: 'MM/DD/YYYY',
onSelect: this.onChangeStart
});
new Pikaday({
field: React.findDOMNode(this.refs.end),
format: 'MM/DD/YYYY',
onSelect: this.onChangeEnd
});
},
The DOM needs to be rendered for Pikaday to hook up to it and the componentDidMount hook lets you hook into that exact event.
componentWillMount is useful when you want to do something programatically right before the component mounts. An example in one codebase I'm working on is a mixin that has a bunch of code that would otherwise be duplicated in a number of different menu components. componentWillMount is used to set the state of one specific shared attribute. Another way componentWillMount could be used is to set a behaviour of the component branching by prop(s):
componentWillMount() {
let mode;
if (this.props.age > 70) {
mode = 'old';
} else if (this.props.age < 18) {
mode = 'young';
} else {
mode = 'middle';
}
this.setState({ mode });
}
componentDidMount only runs once and on the client side. This is important, especially if you're writing an isomorphic app (runs on both the client and server). You can use componentDidMount to perform tasks require you to have access to window or the DOM.
From Facebook's React Page
If you want to integrate with other JavaScript frameworks, set timers using setTimeout or setInterval, or send AJAX requests, perform those operations in this method.
componentWillMount has fewer use cases (I don't really use it), but it differs in that it runs both on the client and server side. You probably don't want to put event listeners or DOM manipulations here, since it will try to run on the server for no reason.
This is an example of an isomorphic web application that makes use of componentWillMount: https://github.com/coodoo/react-redux-isomorphic-example
However, I'm 99% certain that it runs the code inside componentWillMount for no reason on the server side (I think using componentDidMount to ensure it was only run client side would have made more sense) as the code which ensures that fetch promises are fulfilled before rendering the page is in server.js not inside the individual components.
There is discussion on per-component async fetching here: https://github.com/facebook/react/issues/1739 As far as I can tell, there is not a good use case for componentWillMount as far as isomorphism is concerned at least.
In my project which is a dashboarding tool, I have used componentDidMount().
On home page previously saved dashboards appear on the sidebar. I make an ajax call within componentDidMount() of component rendering Homepage, so as to fetch list of dashboards asynchronously after the page has been rendered.
Why React Life Cycle Methods?
Intend to use third-party (Ex D3.js) library with React Component
class Example extends React.component{
constructor(){
// init state
// will be called only once
}
componentWillMount(){
// will be called only once
// will not be triggered when re-rendering
// usually will fetch data that is needed in order
// to render properly from other API
}
shouldComponentUpdate(){
return false
// will not re-render itself after componentDidMount(){}
}
render(){
return (
<div id="chart"></div>
)
}
componentDidMount(){
d3.select(".chart")
.selectAll("p")
// d3.js ........
// d3.js ........
// Usually, this will trigger React to re-render itself,
// but this time will not because we have set
// shouldComponentUpdate to false
}
}
Why React wants to do this?
Since rendering DOM is an expensive operation, React uses the layer of virtual DOM to update only DOM / DOMs that is/are different from previous state.
I'm rewriting my app to use Flux and I have an issue with retrieving data from Stores. I have a lot of components, and they nest a lot. Some of them are large (Article), some are small and simple (UserAvatar, UserLink).
I've been struggling with where in component hierarchy I should read data from Stores.
I tried two extreme approaches, neither of which I quite liked:
All entity components read their own data
Each component that needs some data from Store receives just entity ID and retrieves entity on its own.
For example, Article is passed articleId, UserAvatar and UserLink are passed userId.
This approach has several significant downsides (discussed under code sample).
var Article = React.createClass({
mixins: [createStoreMixin(ArticleStore)],
propTypes: {
articleId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
article: ArticleStore.get(this.props.articleId);
}
},
render() {
var article = this.state.article,
userId = article.userId;
return (
<div>
<UserLink userId={userId}>
<UserAvatar userId={userId} />
</UserLink>
<h1>{article.title}</h1>
<p>{article.text}</p>
<p>Read more by <UserLink userId={userId} />.</p>
</div>
)
}
});
var UserAvatar = React.createClass({
mixins: [createStoreMixin(UserStore)],
propTypes: {
userId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
user: UserStore.get(this.props.userId);
}
},
render() {
var user = this.state.user;
return (
<img src={user.thumbnailUrl} />
)
}
});
var UserLink = React.createClass({
mixins: [createStoreMixin(UserStore)],
propTypes: {
userId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
user: UserStore.get(this.props.userId);
}
},
render() {
var user = this.state.user;
return (
<Link to='user' params={{ userId: this.props.userId }}>
{this.props.children || user.name}
</Link>
)
}
});
Downsides of this approach:
It's frustrating to have 100s components potentially subscribing to Stores;
It's hard to keep track of how data is updated and in what order because each component retrieves its data independently;
Even though you might already have an entity in state, you are forced to pass its ID to children, who will retrieve it again (or else break the consistency).
All data is read once at the top level and passed down to components
When I was tired of tracking down bugs, I tried to put all data retrieving at the top level. This, however, proved impossible because for some entities I have several levels of nesting.
For example:
A Category contains UserAvatars of people who contribute to that category;
An Article may have several Categorys.
Therefore if I wanted to retrieve all data from Stores at the level of an Article, I would need to:
Retrieve article from ArticleStore;
Retrieve all article's categories from CategoryStore;
Separately retrieve each category's contributors from UserStore;
Somehow pass all that data down to components.
Even more frustratingly, whenever I need a deeply nested entity, I would need to add code to each level of nesting to additionally pass it down.
Summing Up
Both approaches seem flawed. How do I solve this problem most elegantly?
My objectives:
Stores shouldn't have an insane number of subscribers. It's stupid for each UserLink to listen to UserStore if parent components already do that.
If parent component has retrieved some object from store (e.g. user), I don't want any nested components to have to fetch it again. I should be able to pass it via props.
I shouldn't have to fetch all entities (including relationships) at the top level because it would complicate adding or removing relationships. I don't want to introduce new props at all nesting levels each time a nested entity gets a new relationship (e.g. category gets a curator).
Most people start out by listening to the relevant stores in a controller-view component near the top of the hierarchy.
Later, when it seems like a lot of irrelevant props are getting passed down through the hierarchy to some deeply nested component, some people will decided it's a good idea to let a deeper component listen for changes in the stores. This offers a better encapsulation of the problem domain that this deeper branch of the component tree is about. There are good arguments to be made for doing this judiciously.
However, I prefer to always listen at the top and simply pass down all the data. I will sometimes even take the entire state of the store and pass it down through the hierarchy as a single object, and I will do this for multiple stores. So I would have a prop for the ArticleStore's state, and another for the UserStore's state, etc. I find that avoiding deeply nested controller-views maintains a singular entry point for the data, and unifies the data flow. Otherwise, I have multiple sources of data, and this can become difficult to debug.
Type checking is more difficult with this strategy, but you can set up a "shape", or type template, for the large-object-as-prop with React's PropTypes. See:
https://github.com/facebook/react/blob/master/src/core/ReactPropTypes.js#L76-L91
http://facebook.github.io/react/docs/reusable-components.html#prop-validation
Note that you may want to put the logic of associating data between stores in the stores themselves. So your ArticleStore might waitFor() the UserStore, and include the relevant Users with every Article record it provides through getArticles(). Doing this in your views sounds like pushing logic into the view layer, which is a practice you should avoid whenever possible.
You might also be tempted to use transferPropsTo(), and many people like doing this, but I prefer to keep everything explicit for readability and thus maintainability.
FWIW, my understanding is that David Nolen takes a similar approach with his Om framework (which is somewhat Flux-compatible) with a single entry point of data on the root node -- the equivalent in Flux would be to only have one controller-view listening to all stores. This is made efficient by using shouldComponentUpdate() and immutable data structures that can be compared by reference, with ===. For immutable data structures, checkout David's mori or Facebook's immutable-js. My limited knowledge of Om primarily comes from The Future of JavaScript MVC Frameworks
The approach at which I arrived is having each components receive its data (not IDs) as a prop. If some nested component needs a related entity, it's up to the parent component to retrieve it.
In our example, Article should have an article prop which is an object (presumably retrieved by ArticleList or ArticlePage).
Because Article also wants to render UserLink and UserAvatar for article's author, it will subscribe to UserStore and keep author: UserStore.get(article.authorId) in its state. It will then render UserLink and UserAvatar with this this.state.author. If they wish to pass it down further, they can. No child components will need to retrieve this user again.
To reiterate:
No component ever receives ID as a prop; all components receive their respective objects.
If child components needs an entity, it's parent's responsibility to retrieve it and pass as a prop.
This solves my problem quite nicely. Code example rewritten to use this approach:
var Article = React.createClass({
mixins: [createStoreMixin(UserStore)],
propTypes: {
article: PropTypes.object.isRequired
},
getStateFromStores() {
return {
author: UserStore.get(this.props.article.authorId);
}
},
render() {
var article = this.props.article,
author = this.state.author;
return (
<div>
<UserLink user={author}>
<UserAvatar user={author} />
</UserLink>
<h1>{article.title}</h1>
<p>{article.text}</p>
<p>Read more by <UserLink user={author} />.</p>
</div>
)
}
});
var UserAvatar = React.createClass({
propTypes: {
user: PropTypes.object.isRequired
},
render() {
var user = this.props.user;
return (
<img src={user.thumbnailUrl} />
)
}
});
var UserLink = React.createClass({
propTypes: {
user: PropTypes.object.isRequired
},
render() {
var user = this.props.user;
return (
<Link to='user' params={{ userId: this.props.user.id }}>
{this.props.children || user.name}
</Link>
)
}
});
This keeps innermost components stupid but doesn't force us to complicate the hell out of top level components.
My solution is much simpler. Every component that has its own state is allowed to talk and listen to stores. These are very controller-like components. Deeper nested components that don't maintain state but just render stuff aren't allowed. They only receive props for pure rendering, very view-like.
This way everything flows from stateful components into stateless components. Keeping the statefuls count low.
In your case, Article would be stateful and therefore talks to the stores and UserLink etc. would only render so it would receive article.user as prop.
The problems described in your 2 philosophies are common to any single page application.
They are discussed briefly in this video: https://www.youtube.com/watch?v=IrgHurBjQbg and Relay ( https://facebook.github.io/relay ) was developed by Facebook to overcome the tradeoff that you describe.
Relay's approach is very data centric. It is an answer to the question "How do I get just the needed data for each components in this view in one query to the server?" And at the same time Relay makes sure that you have little coupling across the code when a component used in multiple views.
If Relay is not an option, "All entity components read their own data" seems a better approach to me for the situation you describe.
I think the misconception in Flux is what a store is. The concept of store exist no to be the place where a model or a collection of objects are kept. Stores are temporary places where your application put the data before the view is rendered. The real reason they exist is to solve the problem of dependencies across the data that goes in different stores.
What Flux is not specifying is how a store relate to the concept of models and collection of objects (a la Backbone).
In that sense some people are actually making a flux store a place where to put collection of objects of a specific type that is not flush for the whole time the user keeps the browser open but, as I understand flux, that is not what a store is supposed to be.
The solution is to have another layer where you where the entities necessary to render your view (and potentially more) are stored and kept updated. If you this layer that abstract models and collections, it is not a problem if you the subcomponents have to query again to get their own data.