Unconventional React
April 24th

Whoami
Sabin Marcu
Software Engineer at R/GA
Been working in web since '09
React Dev since 2015
React trainer @ JSLeague



We take developers from good to great

WE ARE THE JSLEAGUE



Google React
What will you find?



What we'll be focusing on
- React development
- State Managers
- Server communication
- Real time data
- State reconciliation
MobX

GraphQL

React Hooks

Overmind

Styled Components

Linaria

Prisma

Docker

React
Module 1
Module 1
Two types of components:
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
Two types of components:
Stateful Components
Class Components
Smart Components
Etc
Stateless Components
Function Components
Dumb Components
Etc
Module 1
Two types of components:
Stateful Components
Class Components
Smart Components
Etc
Stateless Components
Function Components
Dumb Components
Etc

Module 1
Module 1
Two types of components:
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
Two types of components:
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>
);
}Custom Hooks?

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 };
}Custom Hooks!
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 };
}Custom Hooks!
State Managers
Module 2
Module 2


Module 2
Module 2

Module 2

Comparison
Server Communication
Module 3
Module 3

Module 3

Module 3

Module 3

Complex example
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
Complex example
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
Complex example
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
Complex example
Module 3
query {
users {
posts {
comments {
author {
name
id
}
}
}
}
}Module 3

GraphQL "Verbs"
Query
Mutation
Subscription
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


Tech Used
- React Hooks
- Prisma
- Apollo Client
- Mobx
- Create React App
- React App Rewired
Thank you!
Thank you!
Questions?
Unconventional React
By Sabin Marcu
Unconventional React
- 649