Workshop
git clone https://github.com/monoguerin/workshop.git
cd workshopnpm initThis will create a package.json file where the project information is stored including dependencies and running scripts
npm install --save next react react-dom
{
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
}import React from 'react';
function Home() {
return <div>Welcome to Next.js!</div>;
}
export default Home;Test it by running the next command
npm run devTry building and running locally too as a production build
npm run build
npm startnpm install --save-dev eslint
// Config is broken so we need this
npm install inquirer@6.3
npx eslint --init"rules": {
"react/jsx-filename-extension": [
1,
{
"extensions": [".js", ".jsx"]
}
]
}Add this rule to enable JSX in JS files
Adjust scripts to be run in Heroku
"scripts": {
"dev": "next",
"build": "next build",
"heroku-postbuild": "npm run build",
"start": "next start -p $PORT"
},npm install --save expressCreate a folder called "server" and an "index.js" file inside it
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.get('*', (req, res) => handle(req, res));
server.listen(3000, (err) => {
if (err) {
throw err;
}
console.log('> Ready on http://localhost:3000');
});
})
.catch((ex) => {
console.error(ex.stack);
process.exit(1);
});
Adjust scripts to use our new express server
"scripts": {
"dev": "node server",
"build": "next build",
"start": "NODE_ENV=production node server",
"heroku-postbuild":"npm run build"
},npm install --save express-graphql graphql-toolsconst { makeExecutableSchema } = require('graphql-tools');
const schema = makeExecutableSchema({
typeDefs: `
type Post {
id: Int!
title: String
}
type Query {
posts: [Post]
}
`,
resolvers: {
Query: {
posts: () => [{
id: 1,
title: 'Mi titulo',
}],
},
},
});
module.exports = schema;
Add middleware
const graphqlHTTP = require('express-graphql');
const schema = require('./api');
server.use('/graphql', graphqlHTTP({
schema,
graphiql: true,
}));npm install pm2{
"dev": "pm2 start server --watch",
}npm install apollo-boost react-apollo graphql
Install dependencies
import ApolloClient from 'apollo-boost';
const client = new ApolloClient();
export default client;
Create a folder called "apollo" and a file inside called "client.js"
Let's test our client
import { gql } from "apollo-boost";
client
.query({
query: gql`
{
users {
id
name
email
}
}
`
})
.then(result => console.log(result));npm install isomorphic-fetch es6-promise
Â
import { polyfill } from 'es6-promise';
// ES6 Promise for using isomorphic fetch
polyfill();Â
import ApolloClient from 'apollo-boost';
import fetch from 'isomorphic-fetch';
const client = new ApolloClient({
fetch,
});
export default client;const HOST = process.env.HOST || 'http://localhost:3000';
const client = new ApolloClient({
uri: `${HOST}/graphql`,
fetch,
});const PORT = process.env.PORT || 3000;
module.exports = {
PORT,
HOST: process.env.HOST || `http://localhost:${PORT}`,
};
appConfig.js
{
title: 'Post title 1',
description: 'Lorem ipsum...',
favorite: false
}Create an Array of at least 6 posts with this Object structure
Title
Description....
Â
Â
Â
Delete
Post.js
class Posts extends React.Component {
constructor(props) {
super(props);
this.state = {
posts: POSTS,
};
}
removePost(index) {
const {
posts,
} = this.state;
const newPosts = [
...posts,
];
newPosts.splice(index, 1);
this.setState({
posts: [
...newPosts,
],
});
}
render() {
const {
posts,
} = this.state;
return (
<div>
<h1>Hello, world!</h1>
{posts.map(post => ({
...post,
onClick: this.removePost.bind(this),
})).map(Post)}
</div>
);
}
}const Posts = () => {
const [posts, setPosts] = useState(POSTS);
const removePost = useCallback((index) => {
const newPosts = [
...posts,
];
newPosts.splice(index, 1);
setPosts(newPosts);
}, [posts]);
return (
<div>
<h1>Hello, world!</h1>
{posts.map(post => ({
...post,
onClick: removePost,
})).map(Post)}
</div>
);
};const usePosts = (initialPosts) => {
const [posts, setPosts] = useState(initialPosts);
const removePost = useCallback((index) => {
const newPosts = [
...posts,
];
newPosts.splice(index, 1);
setPosts(newPosts);
}, [posts]);
return {
posts,
removePost,
};
};