Whoami
Sabin Marcu
Software Engineer at R/GA
Been working in web since '09
React Dev since 2015
React trainer @ JSLeague
WE ARE THE JSLEAGUE
React
Module 1
Module 1
export default MyComponent
extends React.Component {
state = { counter: 0 }
render() {
const { counter } = this.state;
return (
<div>
<h1>Count: {counter}</h1>
<input
value={counter}
onChange={(
{target:{value}}
) => this.setState(
{counter: value}
)}
/>
</div>
);
}
}
export default ({ counter, setCounter }) => (
<div>
<h1>Count: {counter}</h1>
<input
value={counter}
onChange={(
{target:{value}}
) => setCounter(
{counter: value}
)}
/>
</div>
);
Module 1
Stateful Components
Class Components
Smart Components
Etc
Stateless Components
Function Components
Dumb Components
Etc
Module 1
Stateful Components
Class Components
Smart Components
Etc
Stateless Components
Function Components
Dumb Components
Etc
Module 1
Module 1
export default MyComponent
extends React.Component {
state = { counter: 0 }
render() {
const { counter } = this.state;
return (
<div>
<h1>Count: {counter}</h1>
<input
value={counter}
onChange={(
{target:{value}}
) => this.setState(
{counter: value}
)}
/>
</div>
);
}
}
export default () => {
const [counter, setCounter] =
useState(0);
return (
<div>
<h1>Count: {counter}</h1>
<input
value={counter}
onChange={(
{target:{value}}
) => setCounter(
{counter: value}
)}
/>
</div>
);
}
Module 1
export default MyComponent
extends React.Component {
state = { hasPosts: false }
componentDidReceiveProps({ posts }) {
if (this.posts !== posts) {
this.setState(
{ hasPosts: posts.length > 0 }
);
}
}
render() {
const { hasPosts } = this.state;
const { posts } = this.props;
return (
<div>
{hasPosts
? posts.map(...)
: this.errorMessage();
</div>
);
}
}
export default ({ posts }) => {
const [hasPosts, setHasPosts] =
useState(false);
useEffect(
() => setHasPosts(...),
[posts]
);
return (
<div>
{hasPosts
? posts.map(...)
: this.errorMessage();
</div>
);
}
Module 1
Module 1
export default (initialData) => {
const [hasPosts, setHasPosts] = useState(false);
const [posts, setPosts] = useState(initialData);
useEffect(
() => setHasPosts(posts.length > 0),
[posts]
);
const [onChange, setOnChange] = useState(null);
useEffect(
() => onChange = ({ target: { value } }) =>
setPosts(value),
[]
);
return { hasPosts, posts, setPosts, onChange };
}
Module 1
export default (initData) => {
const [id, setId] = useState(initData);
const [posts, setPosts] = useState([]);
useEffect(
() => {
const subscription = API.subscribe(id, setPosts);
return () => subscription.unsubscribe();
},
[id];
);
return { id, posts, setId };
}
State Managers
Module 2
Module 2
Module 2
Module 2
Module 2
Server Communication
Module 3
Module 3
Module 3
Module 3
Module 3
Get all users
And for each user get all their posts
And for each post get all comments
And for each comment, get its author
All we need to render is all the author's name and id
Module 3
Get all users
And for each user get all their posts
And for each post get all comments
And for each comment, get its author
Module 3
Get all users (N)
And for each user get all their posts (N*P(N))
And for each post get all comments (N*P(N)*C(P(N)))
And for each comment, get its author (N*P(N)*C(P(N)))
Result: N + N*P(N)(1 + 2 * C(P(N))
Module 3
Module 3
query {
users {
posts {
comments {
author {
name
id
}
}
}
}
}
Module 3
Module 3
mutation {
createUser(name: "Sabin Marcu", email: "sabinmarcu@gmail.com") {
id
isAdmin
}
}
mutation {
updateUser(
where: { email: "sabinmarcu@gmail.com" }
data: { isAdmin: true }
) {
id
isAdmin
}
}
Module 3
mutation {
createUser(name: "Sabin Marcu", email: "sabinmarcu@gmail.com") {
id
isAdmin
}
}
subscription {
user(where: { mutation_in: [CREATED, UPDATED] }) {
node: {
id
name
isAdmin
}
}
}
Module 3