Skip to content

ondrejsika/react-training

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 ondrej@ondrejsika.com and I can run this course in your company.

React Training

2019 Ondrej Sika <ondrej@ondrejsika.com>
https://github.com/ondrejsika/react-training

Example repository to this training is ondrejsika/react-example

Install Node.js & Yarn

Mac

brew install node
brew install yarn

Gitignore & Editor Config

Before you start, you have to setup two things. Gitignore and Editor config. Why?

Gitignore

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

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

Init JavaScript project (package.json)

Create new package.json by:

yarn init

and fill the package info. It will be somethink like this:

yarn init

Prettier

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.

Prettier pre commit hook

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.

Install Next.js & React

yarn add next react react-dom

Install TypeScript

yarn add --dev typescript @types/react @types/node

Add Next.js scripts to package.json

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

Create a First Page

File ./pages/index.js

export default () => {
  return <div>Welcome to Next.js!</div>;
};

Run App

yarn dev

See http://127.0.0.1:3000

Keep running, it will be updated automatically. Try it, change the index.js!

Create Simple Component

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

Basic Construct in JSX

You can write any javascript code inside {} in JSX (javascript with React components), but you have to put it into function.

Conditions (If)

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>
        }
      })()}
    </>
  );
};

Multiple conditions

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

Loops

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

Add Styles to Component

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

Static Rendering

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.

Second Page

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.

Layout in pages/_app.js - Don't Repeat Yourself (DRY)

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

Add CSS & Bootstrap

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;

Deploy to zeit.co

Install now

yarn global add now

Create Now Config

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"
  }
}

Deploy it

Just call

now

See your deployment on Zeit, eg.: https://react-example.ondrejsika.now.sh

Add Images

If you want to use images in Next.js you have to add next-images plugin.

Install next-images plugin

yarn add next-images

Add to next.config.js

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.

Download Example Image

mkdir data
curl -o data/nela.jpg https://raw.githubusercontent.com/ondrejsika/react-training/master/nela.jpg

Use in Page

Now, you can add images to your site using two similar ways.

Import Image

At first, import image

import nela_img from "../data/nela.jpg";

And use it

<img src={nela_img} />

Require from JSX

Just use require in JSX

<img src={require('../data/nela.jpg')} />

Now, you can check it on http://127.0.0.1:3000

Pages in MDX

MDX is Markdown for component era - Markdown + React Components

Official documentation for MDX & Next.js - https://mdxjs.com/getting-started/next/

Install MDX

yarn add @next/mdx @mdx-js/loader

Update Next.js config

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)

Create MDX page

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.

Data in JSON & YAML

JSON

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>

YAML

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>

You are almost done

This course is over, but your journey continues on your own projects. Let me know, how was the cours. Send me email to ondrej@ondrejsika.com.

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.

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published