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
- 550