Client
Server
Database
HTTP
browser
request
html page
Client
Server
Database
HTTP
React in browser, mobile app...
API
request
data
Single page application
Web server
html, js
<html>
<head>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
</head>
<body>
<div id="app">
</div>
</body>
<script>
... your code
</script>
</html>
const myDiv = React.createElement('div', null, 'Hello World');
const label = React.createElement('a', {
href: 'https://google.com'
}, 'Go to Google.com');
<a href="https://google.com">Go to Google.com</a>
children
props
type
<div id="app"></div>
<script>
const myDiv = React.createElement('h1', null, 'Hello World');
ReactDOM.render(myDiv, document.getElementById('app'));
</script>
Hello | Hello |
---|---|
Hello | Hello |
Hello | Hello |
const myNameElement = React.createElement(NameComponent, {
name: 'Martin Nuc'
});
ReactDOM.render(myNameElement, document.getElementById('app'));
function NameComponent(props) {
return React.createElement('h1', null, props.name);
}
Component
Component
Component
Component
Component
Component
Component
User info
ArticleList
Article
Today Weather
Article
I am smart 💡
Hello | Hello | Hello | Hello |
---|---|---|---|
Hello | Hello | Hello | Hello |
Hello | Hello | Hello | Hello |
console.log('Hello world');
npm init
npm
{
"name": "my-package",
"version": "1.0.0",
"description": "This is just description of my awesome package",
"main": "index.js",
"scripts": {
"dev": "nodemon --exec npm run start",
"start": "tsc && node dist/index.js",
"test": "mocha --opts mocha.opts"
},
"author": "Martin Nuc",
"license": "ISC",
"dependencies": {
"@types/chai": "4.0.4",
"@types/mocha": "2.2.43",
"@types/node": "8.0.28",
"@types/sinon": "2.3.4",
"chai": "4.1.2",
"mocha": "3.5.3",
"nodemon": "1.12.1",
"sinon": "3.2.1",
"ts-node": "3.3.0",
"typescript": "2.5.2"
}
}
package.json
"scripts": {
"dev": "nodemon --exec npm run start",
"start": "node index.js",
"test": "mocha --opts mocha.opts"
},
Shortcut for start and test scripts only. For others you have to use npm run
Runs any script from npm.
👉
Runs any script from npm.
👉
import React from 'react';
function App() {
return (
<div className="App">
Hello
</div>
);
}
function App() {
return React.createElement('div', { className: 'App' }, 'Hello');
}
import React from 'react';
function App() {
return (
<div className="App">
Hello
</div>
);
}
function App() {
return React.createElement('div', { className: 'App'}, 'Hello');
}
import React from 'react';
function App() {
return (
<div>
Yes
</div>
<div>
No
</div>
);
}
function App() {
return ????????
}
import React from 'react';
function App() {
return (
<>
<div>
Yes
</div>
<div>
No
</div>
</>
);
}
function App() {
let something = 'hello';
return <div>{something}</div>;
}
function Array() {
let array = [1,2,3];
return <div>
{array.map((item, index) => <span key={index}>{item}</span>)}
</div>;
}
function NameComponent(props) {
return React.createElement('h1', null, props.name);
}
function NameComponent(props) {
return <h1>{props.name}</h1>;
}
function App() {
return <NameComponent name="Martin" />
}
Hello | Hello | Hello | Hello |
---|---|---|---|
Hello | Hello | Hello | Hello |
Hello | Hello | Hello | Hello |
<Table columns={5} rows={2}>
<h1>Hello</h1>
</Table>
function Table(props) {
return (
<table>
<tr>
<td>
{props.children}
</td>
</tr>
</table>
)
}
import React from 'react';
export class Hello extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Martin'
};
}
render() {
const name = this.state.name;
return <div>{name}</div>;
}
}
this.setState({
name: 'Renamed'
});
class Hello extends React.Component {
handleClick() {
this.setState({ name: 'ooooo' })
}
render() {
const { name } = this.state;
return <div>
{name}
<button onClick={this.handleClick}>
change
</button>
</div>
}
}
class Hello extends React.Component {
handleClick() {
this.setState({ name: 'ooooo' })
}
render() {
const { name } = this.state;
return <div>
{name}
<button onClick={this.handleClick}>
change
</button>
</div>
}
}
class Hello extends React.Component {
handleClick() {
this.setState({ name: 'ooooo' })
}
render() {
const { name } = this.state;
return <div>
{name}
<button onClick={() => this.handleClick()}>
change
</button>
</div>
}
}
class Hello extends React.Component {
constuctor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ name: 'ooooo' })
}
render() {
const { name } = this.state;
return <div>
{name}
<button onClick={() => this.handleClick()}>
change
</button>
</div>
}
}
class Hello extends React.Component {
handleClick = () => {
this.setState({ name: 'ooooo' })
}
render() {
const { name } = this.state;
return <div>
{name}
<button onClick={this.handleClick}>
change
</button>
</div>
}
}
render() {
const random = Math.random();
if (random < 0.5) {
return <span>lower</span>
} else {
return <span>higher</span>
}
}
render() {
const random = Math.random();
return <span>
{random < 0.5 ? 'lower' : 'higher'}
</span>
}
beware of setting state after component has been unmounted
solutions:
class ChildComponent extends React.Component {
handleClick = () => {
this.props.doWork();
}
render() {
return <button onClick={this.handleClick}>emit event</button>;
}
}
<ChildComponent doWork={() => console.log('triggered')} />
parent component:
child component:
class Component extends React.Component {
constructor() {
this.state = {
value: ''
};
}
handleChange = (event) => {
this.setState({
value: event.target.value
});
}
render() {
return <>
{this.state.value}
<input value={this.state.value} onChange={this.handleChange}>
</>
}
}
import axios from 'axios';
GET https://api.chucknorris.io/jokes/random
Component
User info
JokeFetcher
Joke
I am smart 💡
data down
import cn from 'classnames';
...
<div class={cn({ invalid: this.state.invalid })}>
</div>
export class CounterState extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0
}
}
inc = () => {
this.setState({counter: this.state.counter + 1});
}
dec = () => {
this.setState({counter: this.state.counter - 1});
}
render() {
return this.props.children({
counter: this.state.counter,
increment: this.inc,
decrement: this.dec
});
}
}
render() {
return <CounterState>
{({counter, increment}) =>
<>
<div>Current value: {counter}</div>
<button onClick={increment}>inc</button>
</>
}
</CounterState>
}
<ValidatedInput type="number"
name="age"
validator={value => value < 10} />
validator fn passed via props
export class ValidatedInput extends React.Component {
constructor(props) {
super(props);
this.state = {
value: '',
invalid: true
}
}
handleChange = (event) => {
const value = event.target.value;
this.setState({value});
this.setState({
invalid: !this.props.validator(value)
});
}
render() {
return <div class={cn({ invalid: this.state.invalid })}>
<input {...this.props} value={this.state.value} onChange={this.handleChange} />
</div>
}
}
validator fn passed via props
const schema = yup.object().shape({
email: yup.string().required().email(),
age: yup.number().required().positive().integer()
})
const initialValues = {
email: '',
age: 0
}
export function MyForm() {
return (
<Formik
initialValues={initialValues}
validationSchema={schema}
onSubmit={values => console.log(values)}
render={() => (
<Form>
<Field type="email" name="email" />
<ErrorMessage name="email" component="div" />
<Field type="number" className="error" name="age" />
<ErrorMessage name="age" className="error" component="div"/>
<button type="submit">
Submit
</button>
</Form>
)}
/>
);
}
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
function App() {
return (
<Router>
<Link to="/">Home</Link>
<Link to="/categories">About</Link>
<Link to="/categories/animals">Joke about animals</Link>
<Link to="/categories/history">Joke about history</Link>
<Route exact path="/" component={Home} />
<Route path="/categories" component={JokeCategories} />
<Route path="/categories/:category" component={Joke} />
</Router>
);
}
function Joke({match}) {
return (
{match.params.category}
);
}
import React, { useState } from 'react';
function Counter() {
const [counter, setCounter] = useState(0);
function handleIncrement() {
setCounter(counter + 1);
}
return <button onClick={handleIncrement}>{counter}</button>
}
initial value
export const MyMouse = () => {
const [mousePosition, setMousePosition] = useState({x: 0, y: 0});
const onMouseMove = event => {
setMousePosition({
x: event.clientX,
y: event.clientY
});
};
useEffect(() => {
window.addEventListener('mousemove', onMouseMove);
return () => {
window.removeEventListener('mousemove', onMouseMove);
};
}, []);
const {x, y} = mousePosition;
return (
<div>My mouse x position is {x} and y position is {y}</div>
);
};