This course is not finished yet and it is under intensive development. Try on own risk ;) If you found a bug or improvement, create issue or pull request. Or let me know by email. Thanks. -- Ondrej Sika
Are you interested in this course? Send me email to [email protected] and I can run this course in your company.
2019 Ondrej Sika <[email protected]>
https://github.com/ondrejsika/react-training
Example repository to this training is ondrejsika/react-example
brew install node
brew install yarn
Before you start, you have to setup two things. Gitignore and Editor config. Why?
You probably want to use Git. If your directory contain some files you don't want to manage using git, you have to ceate .gitignote
and specify them there.
# .gitignore
node_modules
.next
out
.vscode
.DS_Store
If you want to know more about Git, check out my Git Training.
Editor config is a file wich set up your editor to formatting standart defined in .editorconfig
file. You can chose tabs or spaces, ident size and much more. Here is my basic config:
# .editorconfig
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
max_line_length = null
Create new package.json
by:
yarn init
and fill the package info. It will be somethink like this:
We use Prettier as a code formater.
Install prettier as a development dependency.
yarn add --dev prettier
Install also VS Code extension for Prettier too.
You can also add scripts for prettier validation & auto reformat code.
{
"scripts": {
"prettier-check": "prettier -l '**/*.js'",
"prettier-write": "prettier --write '**/*.js'"
}
}
You want reformat just your source code, not a node modules or minified build.
You have to create .prettierignore
(with same syntax as .gitignore) and specify what you want ingnore.
node_modules/
out/
.next/
If you want to check all your project files, you can use yarn run prettier-check
.
If you want to fix format of your js files, use yarn run prettier-write
.
You can also create pre commit hook which protect you from commit unformated code into repository. If you want to check format before every commit, create pre commit hook by:
cat > .git/hooks/pre-commit <<EOF
#!/bin/sh
yarn run prettier-check
EOF
chmod +x .git/hooks/pre-commit
If you want to skip this validation you have to use git commit
with -n
or --no-verify
parameter.
yarn add next react react-dom
Install TypeScript
yarn add --dev typescript @types/react @types/node
{
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
}
File ./pages/index.js
export default () => {
return <div>Welcome to Next.js!</div>;
};
yarn dev
Keep running, it will be updated automatically. Try it, change the index.js
!
Create file ./components/Hello.tsx
import React, { FunctionComponent } from "react";
type HelloProps = {
name: string;
};
const Hello: FunctionComponent<HelloProps> = ({ name }) => (
<div>
<h1>Hello {name}</h1>
</div>
);
export default Hello;
Use it in index.js
import Hello from "../components/Hello";
export default () => {
return (
<>
<Hello name="Zuz" />
</>
);
};
and check it out http://127.0.0.1:3000
You can write any javascript code inside {}
in JSX (javascript with React components), but you have to put it into function.
Instead of this:
// pages/index.js
// NOT working example
import Hello from "../components/Hello";
export default () => {
let name = "Zuz";
return (
<>
{
if (name) {
<Hello name="Zuz" />
}
else {
<h1>Hello unknown</h1>
}
}
</>
);
};
You have to put your JS code into function and call it.
<>
{(()=>{
return ...
})()}
</>
Your file will be like this.
// pages/index.js
import Hello from "../components/Hello";
export default () => {
let name = "Zuz";
return (
<>
{(() => {
if (name) {
return <Hello name={name} />;
}
else {
return <h1>Hello unknown</h1>
}
})()}
</>
);
};
If you have more than one condition, it will be hard to that this way. You can create array and append components you want to render and then, return whole array (and will be rendered).
Create the example file pages/multiple-if.js
:
// pages/multiple-if.js
export default () => {
let count = 2;
return (
<>
{(() => {
let out = [];
if (count >= 1) {
out.push(<h1>H1</h1>);
}
if (count >= 2) {
out.push(<h2>H2</h2>);
}
if (count >= 3) {
out.push(<h3>H3</h3>);
}
return out;
})()}
</>
);
};
and see http://127.0.0.1:3000/multiple-if
You can loop array very simply, like this:
// pages/loops.js
export default () => {
let fruits = ["orange", "apple", "banana"];
return (
<>
<ul>
{(() => {
return fruits.map((el, i) => {
return <li key={i}>{el}</li>;
});
})()}
</ul>
</>
);
};
See http://127.0.0.1:3000/loops
Update our hello component like that:
export default props => {
return (
<>
<h1
style={{
color: "green",
backgroundColor: "lightblue"
}}
>
Hello {props.name}
</h1>
</>
);
};
You can add styles using style
property. Styles must be object, where key is camel case name of css property and value is string with its value.
Check it out http://127.0.0.1:3000
You need to add pages you want to render statically to next.config.js
. You have to replace module.exports = {};
with:
module.exports = {
exportTrailingSlash: true,
exportPathMap: async function(defaultPathMap) {
return {
'/': { page: '/' },
};
}
};
Add static build script to package.json
:
{
"scripts": {
"static": "yarn run build && next export",
}
}
Now you can build site using:
yarn run static
And see your statically builded website in out/
.
Dont forget to add the out
to .gitignore
.
If you want create another page, you can create pages/about-me.js
export default () => {
return (
<>
<h1>About me</h1>
</>
);
};
You have to add that page also to next.config.js
:
module.exports = {
exportTrailingSlash: true,
exportPathMap: async function(defaultPathMap) {
return {
'/': { page: '/' },
'/about-me': { page: '/about-me' },
};
}
};
Because you've edited Next.js config, you have to restart server.
Then, check it out http://127.0.0.1:3000/about-me. You can also build static site.
Create file pages/_app.js
which defines your's app layout. You can also import CSS there:
import React from "react";
import App, { Container } from "next/app";
class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<p>
<a href="/">Index</a> ~ <a href="/about-me">About me</a>
</p>
<Component {...pageProps} />
</Container>
);
}
}
export default MyApp;
Check it out http://127.0.0.1:3000
You have to install Bootstrap first.
yarn add bootstrap
Then you have to install & configure Next.js CSS plugin. Install it by:
yarn add @zeit/next-css
And add to bottom of next.config.js
:
const withCSS = require("@zeit/next-css");
module.exports = withCSS(module.exports);
After any change in next.config.js
you have to restart dev server.
Now, you can import style to your _app.js
. Just add import of css:
// _app.js
// Imported CSS
import "bootstrap/dist/css/bootstrap.css";
Now, you can use Bootstrap, for example add conteiner into your layout in _app.js
,
your file will be like this:
import React from "react";
import App, { Container } from "next/app";
// Imported CSS
import "bootstrap/dist/css/bootstrap.css";
class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<div className="container">
<p>
<a href="/">Index</a> ~ <a href="/about-me">About me</a>
</p>
<Component {...pageProps} />
</div>
</Container>
);
}
}
export default MyApp;
yarn global add now
Create now.json
:
{
"version": 2,
"name": "react-example",
"builds": [
{
"src": "package.json",
"use": "@now/static-build",
"config": { "distDir": "out" }
}
]
}
and add script to package.json
:
{
"scripts": {
"now-build": "yarn run static"
}
}
Just call
now
See your deployment on Zeit, eg.: https://react-example.ondrejsika.now.sh
If you want to use images in Next.js you have to add next-images plugin.
yarn add next-images
Add those lines to bottom of your next.config.js
const withImages = require('next-images')
module.exports = withImages(module.exports)
And restart your dev server.
mkdir data
curl -o data/nela.jpg https://raw.githubusercontent.com/ondrejsika/react-training/master/nela.jpg
Now, you can add images to your site using two similar ways.
At first, import image
import nela_img from "../data/nela.jpg";
And use it
<img src={nela_img} />
Just use require in JSX
<img src={require('../data/nela.jpg')} />
Now, you can check it on http://127.0.0.1:3000
MDX is Markdown for component era - Markdown + React Components
Official documentation for MDX & Next.js - https://mdxjs.com/getting-started/next/
yarn add @next/mdx @mdx-js/loader
Add to module.exports
this pageExtensions: ['js', 'jsx', 'mdx']
.
It will be look like:
module.exports = {
pageExtensions: ['js', 'jsx', 'mdx'],
exportTrailingSlash: true,
exportPathMap: async function(defaultPathMap) {
return {
'/': { page: '/' },
'/about-me': { page: '/about-me' },
};
}
};
And you have to add plugin for MDX to bottom of your Next.js config:
const withMDX = require('@next/mdx')({})
module.exports = withMDX(module.exports)
You have to create a page with .mdx
suffix in your pages
dir, for example pages/mdx.mdx
whith content:
import Hello from '../components/Hello';
<Hello name='MDX!'/>
This is a [Next.js](https://nextjs.org) page written in MDX (Markdown + React Components).
## This is H2 Header
Some text.
### This is H3 Header
And some code
You can also add link to this page to navigation in file pages/_app.js
:
<a href="/">Index</a> ~ <a href="/about-me">About me</a> ~ <a href="/mdx">MDX</a>
And you have to add page /mdx
to static build configuration in your Next.js config. File next.config.js
will be look like:
module.exports = {
pageExtensions: ['js', 'jsx', 'mdx'],
exportTrailingSlash: true,
exportPathMap: async function(defaultPathMap) {
return {
'/': { page: '/' },
'/about-me': { page: '/about-me' },
'/mdx': { page: '/mdx' },
};
}
};
const withImages = require('next-images')
module.exports = withImages(module.exports)
const withCSS = require("@zeit/next-css");
module.exports = withCSS(module.exports);
const withMDX = require('@next/mdx')({})
module.exports = withMDX(module.exports)
And that's it. Try yarn run dev
and see http://127.0.0.1:3000/mdx or check out static build using yarn run static
.
Create example json file data/demo.json
:
["Apple", "Orange", "Banana"]
You can import JSON into Next.js directly without any configuration. Just import json file like this:
// index.json
import json_file from "../data/example.json";
And add usage of data (add to index.js
):
// index.json
<h2>JSON Data</h2>
<ul>
{json_file.map((el, i) => {
return <li key={i}>{el}</li>;
})}
</ul>
You need a plugin (next-yaml) for loading YAML files. You have to install it:
yarn add next-yaml
And use it in next.config.js
, add to botom of file:
// next.config.js
const withYAML = require("next-yaml");
module.exports = withYAML(module.exports);
and restart dev server.
Create example YAML data/example.yaml
:
# data/example.yaml
- Apple
- Orange
- Banana
Now, you can import & use YAML (.yaml & .yml) as JSON files described before.
Just import YAML in index.js
and use it:
// index.json
import yaml_file from "../data/example.yaml";
And add usage of data (add to index.js
):
// index.json
<h2>YAML Data</h2>
<ul>
{yaml_file.map((el, i) => {
return <li key={i}>{el}</li>;
})}
</ul>
This course is over, but your journey continues on your own projects. Let me know, how was the cours. Send me email to [email protected].
If you like the course, please Tweet some recommendation with my Twitter handle @ondrejsika or add me on LinkedIn /in/ondrejsika and write me a recomendation.
In case of any questions, let me know by email.