Quickstart
A quick dive into getting started with Lore
A quick dive into getting started with Lore
In this step we're going to fetch the user for each tweet, so that we can display the proper nickname and avatar.
You can view the finished code for this step by checking out the
fetching
branch of the completed project.
Before we can fetch users, we need to create a model to represent the resource. Run this command to create a user model:
lore generate model user
This will place a file called user.js
in src/models
and, just like when you created the tweet
model, you will now have access to a set of actions and reducers for interacting with the /users
endpoint.
Next we need to fetch the user who created the tweet. Open the Tweet
component and wrap it with connect
, but this time we're going to use a different string in the getState()
method:
// src/components/Tweet.js
...
import { connect } from 'lore-hook-connect';
export default connect(function(getState, props) {
const { tweet } = props;
return {
user: getState('user.byId', {
id: tweet.data.userId
})
};
})(
createReactClass({
displayName: 'Tweet',
...
})
);
// src/components/Tweet.js
...
import { connect } from 'lore-hook-connect';
class Tweet extends React.Component {
...
}
export default connect(function(getState, props) {
const tweet = props.tweet;
return {
user: getState('user.byId', {
id: tweet.data.userId
})
};
})(Tweet);
// src/components/Tweet.js
...
import { connect } from 'lore-hook-connect';
@connect(function(getState, props) {
const tweet = props.tweet;
return {
user: getState('user.byId', {
id: tweet.data.userId
})
};
})
class Tweet extends React.Component {
...
}
The string we're passing to the getState()
method this time is user.byId
. But unlike the tweet.find
call, this time we need to provide an argument; the id
of the user you want to retrieve. If the user exists in the store, it will be returned immediately. If not, an action will be invoked to fetch that user from the API.
You can learn more about the
byId
blueprint here.
With this change in place, refresh the browser and you should see each tweet attributed to the correct user.
At this point both our
Feed
andTweet
components are fetching real data, which means you can safely delete thegetDefaultProps()
method from both components if you'd like. Seeing as we are no longer using them to insert mock data, they no longer serve a purpose.
Below is a list of files modified during this step.
export default {
};
export default {
}
export default {
}
import React from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import moment from 'moment';
import { connect } from 'lore-hook-connect';
export default connect(function(getState, props) {
const { tweet } = props;
return {
user: getState('user.byId', {
id: tweet.data.userId
})
};
})(
createReactClass({
displayName: 'Tweet',
propTypes: {
tweet: PropTypes.object.isRequired,
user: PropTypes.object.isRequired
},
getDefaultProps() {
return {
user: {
id: 1,
data: {
id: 1,
nickname: "lucca",
avatar: "https://cloud.githubusercontent.com/assets/2637399/19027072/a36f0c7a-88e1-11e6-931e-7f67fe01367b.png"
}
}
};
},
render() {
const { tweet, user } = this.props;
const timestamp = moment(tweet.data.createdAt).fromNow().split(' ago')[0];
return (
<li className="list-group-item tweet">
<div className="image-container">
<img
className="img-circle avatar"
src={user.data.avatar} />
</div>
<div className="content-container">
<h4 className="list-group-item-heading title">
{user.data.nickname}
</h4>
<h4 className="list-group-item-heading timestamp">
{'- ' + timestamp}
</h4>
<p className="list-group-item-text text">
{tweet.data.text}
</p>
</div>
</li>
);
}
})
);
import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { connect } from 'lore-hook-connect';
class Tweet extends React.Component {
render() {
const { tweet, user } = this.props;
const timestamp = moment(tweet.data.createdAt).fromNow().split(' ago')[0];
return (
<li className="list-group-item tweet">
<div className="image-container">
<img
className="img-circle avatar"
src={user.data.avatar} />
</div>
<div className="content-container">
<h4 className="list-group-item-heading title">
{user.data.nickname}
</h4>
<h4 className="list-group-item-heading timestamp">
{'- ' + timestamp}
</h4>
<p className="list-group-item-text text">
{tweet.data.text}
</p>
</div>
</li>
);
}
}
Tweet.propTypes = {
tweet: PropTypes.object.isRequired,
user: PropTypes.object.isRequired
};
export default connect(function(getState, props) {
const tweet = props.tweet;
return {
user: getState('user.byId', {
id: tweet.data.userId
})
};
})(Tweet);
import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { connect } from 'lore-hook-connect';
@connect(function(getState, props) {
const tweet = props.tweet;
return {
user: getState('user.byId', {
id: tweet.data.userId
})
};
})
class Tweet extends React.Component {
static propTypes = {
tweet: PropTypes.object.isRequired,
user: PropTypes.object.isRequired
};
render() {
const { tweet, user } = this.props;
const timestamp = moment(tweet.data.createdAt).fromNow().split(' ago')[0];
return (
<li className="list-group-item tweet">
<div className="image-container">
<img
className="img-circle avatar"
src={user.data.avatar} />
</div>
<div className="content-container">
<h4 className="list-group-item-heading title">
{user.data.nickname}
</h4>
<h4 className="list-group-item-heading timestamp">
{'- ' + timestamp}
</h4>
<p className="list-group-item-text text">
{tweet.data.text}
</p>
</div>
</li>
);
}
}
export default Tweet;
Next we're going to learn how to implement an authentication flow.