GABRIEL GOMARIZ: Hello, and welcome.
This is frontend development with React and Pagedraw.
My name is Gabriel Gomariz, and I'm Harvard class of 2017.
I graduated in computer science.
And now I'm living in San Francisco working on a startup called page draw.
We work on automating firm development.
I'll get into a little bit more of what that means.
But before we dive into that, I would like
to talk a little bit about React, which is a JavaScript framework that's
doing a lot of buzz in the tech community these days.
React is developed by Facebook.
If you want to read more, you can always go to reactjs.org.
That's their official website.
And it is a JavaScript library for building user interfaces.
So the idea is if you want to build cool, awesome modern apps--
something like Facebook, something like Airbnb--
that are not static, but they have a lot of stuff going on.
You should probably be looking into using something like React.
To understand why React is cool, I'd like
to first go into a little bit of history of these things.
So the quintessential way that you learn in cs50 probably of using JavaScript,
if you recall JavaScript, you can use to ship code to the client side
to the browser to do changes that do not need
to refresh the page on your browser.
So if you want, for example, to on something and have a pop up appear,
or something dynamic show up on the screen
without having to refresh the page, probably you're using JavaScript.
The way that you do that is you traditionally
do something like var in JavaScript, element or root
equals document dot get element by ID.
You pass it some ID, Hello World.
And then as soon as some event happens, for example someone clicks
on a button, what you do is you say, root
dot inner HTML equals my new content.
OK, so this is kind of like the quintessential JavaScript example.
And I want you to notice that this is very mutational.
This is very imperative, we call it.
And that's very important for understanding React
because React is kind of the opposite of that way of thinking.
Why I call this mutational is that you're first fetching
some element that's on the screen.
We can actually do this live here.
So if I inspect Element and go to the console,
I can actually do this in real JavaScript, where if I type in zero,
this has essentially selected that element.
And I can say, zero dot inner text equals hello world.
And there you go.
It changed right there using JavaScript into hello world.
But this is mutational because I'm fetching some part of the screen,
and I'm saying, go and change it.
React has a different way to do this.
So first thing I'm going to do is I'm going
to use this little tool called create React app that
just creates a React app for you.
And I'll call my app movies.
We're going to be working with movies today.
Oh, there's already a directory called movies.
Let me remove it.
Permission denied.
Let's just call it a different thing--
Movies example.
So this is making sure the React is installed,
and it's creating a directory that has all of the initial files
that I'm going to need to do a React app.
There we go.
So now we can cd into movies example.
We're going to see that we have these node modules here, which
essentially all of your libraries.
There's some stuff happening.
Package JSON is essentially giving me some metadata about my product.
But the really important folder is in source.
So if you're going to source, there are a couple of files here.
The most important ones are this index, dot js and app dot js.
So the idea of index dot js is very simple.
It is just importing this app from dot flash app,
and then calling ReactDOM dot render.
All the rest is like also doing some stuff,
but it's not as important as those two lines-- line 4 and line 7 here.
So ReactDOM dot render is just saying, render
this React component called app onto the screen into this document
dot get element by ID root.
That's kind of the only mutational thing we're
going to do here in the similar style of the JavaScript that we wrote before.
But app is a React component.
So let's dive into what that is.
So class app extends component that's imported from React.
And it's a pretty simple file that just implements a single function.
This is a class that implements this function called render.
And render is the most important function in React.
The idea is instead of saying, OK, draw the screen.
And then if you want something to change, you go in there
and say, change it in an imperative way.
What React does is it tells you to implement
this render function that knows how to paint things
to the screen at all times.
And you can never really go in and change something explicitly,
or say like, what we just did here where we changed this React into Hello World.
You can never do that.
The only thing you can do is call render.
And that's really interesting.
So the idea is that instead of going in and changing
just a little piece of the screen, you have to rerender
the whole thing every single time.
The history of this is kind of interesting.
It might not look very compelling at first, because you might be thinking,
OK, if I'm rerendering the whole screen, this sounds kind of inefficient.
Because I could just go in and just change that one little Hello
World there.
And that's a lot more efficient, because I don't have to rerender everything.
Sure, that's true.
But React can do some interesting tricks behind the scenes
to make that faster for you.
But the idea is that, although it might not sound very compelling at first,
for really complicated apps, it is very compelling.
Kind of story of this is related to a lot of game development.
In games, you have a lot of stuff going on.
So there's a character on the screen.
The character is moving around, and there is stuff happening.
There's wind coming.
There's leaves falling.
There's enemies all around.
This is very, very complicated.
And if you try to do things in this mutational way, where
you say, for example, well, when you hit spacebar,
the character's going to jump.
OK, so let's go in and make the character jump.
But when the character jumps, something can
happen to the enemy that makes the enemy go to the right, for example,
because you hit them or something like that.
So one event will trigger the other event.
So you get, OK, the character jumped.
Now go in and mutate the enemy to make it go a little bit to the right.
But the enemy going to the right can trigger another mutation
that's going to make something else on the screen go to a different place.
So you have these cascading effects of one event triggering the other event,
triggering the other event.
It might seem reasonable at first, but if you
have a very complicated app like a video game with a lot of graphics going on,
all these cascading events from the point of view of a developer
might become completely impossible to work with.
Because you might find an event happening
that you have no idea why it happened, what's going on,
and why the character just became blue and lost his head all of a sudden,
because one little leaf on the left side of the screen
just triggered a huge waterfall of events like this.
So the way that the game developers deal with this is that they say,
OK, let's have this abstract world that doesn't have anything
to do with the screen.
So we don't worry about painting the screen.
So we just have these abstract concepts like the character position--
two numbers, x and y.
The enemy positions-- so you might have an array that has a bunch of x and ys
as well.
You might have, for example, the direction of the wind.
So this is kind of like just abstract numbers, just
an abstract notion of everything.
In React, we call this state.
So we have this state, and then you have this function,
which in React is going to call render which knows how to get a state
and paint it to the screen.
And that's all basically React is.
That's basically the way that people in game development
have solved these problems for many years now.
And the idea is that if you want your character to jump, you don't say, hey,
your Pixel right there, move a little bit to the right.
You don't say that.
What you do is you just change the state, and then you recall render.
So you change the state.
You say, like, position x is now 50, and you recall render.
And render just rerenders the whole screen.
But then it's smart, so it takes a difference
between what was the last screen and what is the new screen.
And then using this difference, it just updates up correct pixels.
This is a lot more sane because now you can't have one event triggering
the other, because you're not listening anymore
to things happening on the screen.
So, like, oh, one jump made some other thing happen.
This is not what's happening anymore.
You just do this data mutation-- the abstract data mutation--
and then you get essentially a painting from that.
It is really important for this reason that this render function,
both in React and in this game example that we just went over,
is what we computer scientists call pure.
Because the idea of pure is essentially that every time you
call render with the same arguments, with the same state,
it outputs the exact same thing.
So render cannot have a thing that changes its own state in the middle
of it.
And that's really, really important, because if you
have changing a variable--
let's say that this render in this case, it takes some state.
And I'm going to add this here, so you guys understand.
So this is a little bit of JavaScript syntax
where I'm going to initialize some state.
I'm going to say this dot state equals name equals David.
And now, anywhere in your render function,
you can actually refer to this state.
Again, this is the same analogy as like your character position.
And you can say in a new paragraph.
You can just open curly braces to go into JavaScript mode,
and say, this dot state dot name.
This is going to refer to that variable for you.
And after we actually open or app, which we probably
should have done already, with NPM start,
this is going to run our dev server.
This is our simplest of React apps.
That is not allowed before super.
This is more JavaScript syntax.
I have to call super in the constructor.
There you go.
And I didn't say Hello in here, so let's do a Hello, David.
So this is probably one of the simplest React examples.
It has this Welcome to React idea.
And it does Hello, David in here with this state.
And the idea is, again, if I change this state to be Hello, Gabriel, render
didn't change.
But render knows how to take a state and paint it on the screen.
So it's going to paint it on the screen as Hello, Gabriel.
And now, if any event happens--
let's start doing that.
Let's say there is a button.
Button Click me.
Let's see if our button exists here.
It does.
It doesn't do anything yet.
Let's make it do something.
I'm going to attach an on Click Handler to this button.
This dot [? onClickMe. ?] And in JavaScript, for reasons, I
have to do this dot bind this, so I can access the this variable inside
of the unClick me function.
I'm going to define the [? onClickMe ?] function.
And what this function is going to do is just change the state.
So again, same idea.
If the character press spacebar, you don't change what's on the screen.
You just change the position, and then render
takes care of updating the data on the screen.
So you say, this dot set state name to be Cats.
So now this says, Hello, Gabriel.
If you click me, it also says, Hello, Cats.
You just literally changed the state, and then it
takes care of calling render for you and doing all the rest.
And that's basically all there is to React.
This is the core idea of everything that you need
to know to get going with a React app.
You have some state.
You have a function that's special called render.
It knows how to take a state and paint it on the screen.
And event handlers, like this unClick right here, can mutate the state.
Note again, take a moment to notice the difference between mutating the state
and actually doing that get element by ID,
imperatively setting the inner HTML to Cats.
You would, in this case, achieve the exact same end goal,
but it is different.
Because there is this state step, and then
calling the render function, which for much more complicated apps,
is a really, really big deal.
And basically, you can actually now go on
and start just writing your React apps, which is really cool.
This, by the way right here, is what we call JSX.
It's essentially an embedding of HTML in CSS.
Very similar-- the HTML is not quite HTML, but it's very close--
inside of JavaScript code.
So the reason we can return this bunch of HTML inside of some JavaScript code
is because of this language called JSX that eventually
gets compiled all down to JavaScript.
And that's also part of React tool chain.
And this is all there is to React.
So again, you have some state.
You can mutate it when events happen, and then
render those sort of paintings on the screen.
Now where Pagedraw comes in is essentially takes over
this render function for you.
So Pagedraw automates a way for a lot of frontend development,
but only kind of the dumb parts of frontend development.
We do not want to take care of any of this unClick
me logic, because this could be much more complicated than just
setting a state to a different name.
This cold be arbitrarily complicated.
What we do is we just take care of the HTML
and the CSS part for you, which lives inside of your render function.
So in order to do something with Pagedraw, what I will do here
is first, let's open up our Pagedraw doc, which is right here.
And again, if you want to follow this, you
can just go to documentation.pagedraw.io,
and click on our tutorial, which will have everything
that I'm showing you today.
And this is our interface, our editor.
You can hit R to draw rectangles.
You can hit A to draw art boards.
Ar boards are, for us, equivalent to Pagedraw components.
So every time you draw an art board, you get React components.
And the cool thing is that you can click on Export code,
and we automatically export code for this one component for you.
This is GSX again, and this is CSS.
I already have a sketch file that a designer in our team made earlier.
If you don't use Sketch, you can just literally draw in here.
Or if you are a designer, and you like using Sketch already,
you can just import it like I'm about to do.
So today, we're going to build a movie app.
This is importing.
Takes a second, but there it is.
Cool.
So I had a designer do this in Sketch where they just literally drew.
Let me open up sketch, so you guys can see.
Literally just drew this idea of an app for movies, called Movie Time.
Again. there's nothing dynamic about it.
There's no code here.
This is just a static drawing.
It's like you went to Photoshop, or Sketch in this case,
and you just draw lines and text.
Now we're going to do what we call productionizing.
We're going to bring this into production using Pagedraw,
and I'm going to show you how to make this app come
to life while using Pagedraw to implement your react render
functions for you.
Before we dive in, you can check out what the final version looks like.
There's a movie here, Monty Python and the Holy Grail, one of my favorites.
You can write comments about the movie.
Hi, I love this movie.
Great.
And you can choose a rating for it.
So this is just to showcase some of Pagedraw plus React capabilities,
so you're, hopefully, well-equipped to create something like this yourself.
And if you click on the movie, it changes
to another of my favorite movies--
Back to the Future.
So this is the app we're going to build today, so let's get started.
Now I just imported the Sketch file.
But again, as I said, it does not have any dynamic data.
So the first step that I'm going to do is I'm going to hit D for dynamic.
And I'm going to click on everything that should be dynamic that
should be coming from the database.
For example, Pulp Fiction here should be dynamic.
1994 also should be dynamic.
And this text is a description should be dynamic.
The director name should be dynamic.
This comment should probably be dynamic too.
And the image are the first things that I see that are dynamic.
These stars are also dynamic, but I'll get to them later.
OK, cool.
Now what did I just do?
I essentially said that these things are coming from some JavaScript.
In Pagedraw, if I go to the code tab, and I click anywhere inside
of this component to select it, the code tab's
going to have a bunch of object inputs which are essentially
variables, which are your state that we automatically define for you.
They're all run of type string, except this one, which is of type image.
And they have these names that are pretty standard default names
that we created for you, called text, text 2, text 3, text 4.
Again, because in Pagedraw this is a React component,
this specifies what inputs, what state, that component's in.
And here is where are they used.
So if I click on this text input here, it
says that, this dot props dot image source is going to be this image.
Props is a thing that definitely deserves a word.
In React.
I just talked about state.
It turns out that there is a different thing called props that it turns out,
you can have multiple components.
So if you have like a component 2 in React,
you can actually use that inside of our render functions,
and do something like component 2.
The way to pass down variables from component 1 to component 2
is through props.
So you can pass a variable called foo equals
this dot state dot name, for example.
And inside of the render function of component 2,
you're going to be able to refer to this foo variable.
So let's actually do the definition here, so you guys understand.
Class app, class component 2 extends component.
I'll just define a very simple render function
that just does this dot props dot foo.
And instead of passing this as state dot name,
I can pass whatever JavaScript I want here.
So I'm going to do Hello plus CS 50.
So again, just showcasing the idea of props.
Hello, CS50 is appearing here.
We're using multiple components.
So this idea of props is essentially state
that you can pass down to other components.
You don't really need, strictly speaking, two components
or more components.
But in order to make your app easier and more usable and more sane to work with,
you probably want to separate those components,
or even put some in different files, different folders, how every you want.
React is not too opinionated about what you do with your components
or where you should place them.
It's kind of very up to you, which is really cool.
All that React is doing is this state to render painting idea.
And all of the rest is up to you, and it's just JavaScript,
which I particularly really like.
OK, now that you know what props are, let's go back
and see what Pagedraw did there for us.
So it defined that this component takes in a bunch of props.
These are the types, and these are the names.
And then he uses these props in all of the particular things that we clicked.
So text 4 is the director here.
And I'd actually already go ahead and change some of these names
to become more sane.
So text 4 is going to be just director.
And I'm making these up right now.
This guy's the movie title, which was just text movie title.
Text 2 is the movie year.
Text 5 is interesting, because this, I actually want to make it a list.
So let's do that before.
Because I want to have multiple comments here.
So the way to do this is I can select both of the things
that I wanted to go into list.
This little line here and this text.
And I can wrap it.
This is just going to basically draw a block around it.
So I can say that this block is going to repeat.
And now I just click Repeat here, and bam,
Pagedraw has created a list for me.
Again, in the code sidebar, it says, this is a props dot list,
and each item in the list is going to be called item.
[INAUDIBLE] for now.
Remember that, at all times, you can always export the code
and see what we're doing there for you.
So for example, here we're doing this dot props dot movie title.
And the idea is you shouldn't really care about these class names and all
of this stuff.
This should be kind of like a black box to you,
where you're just going to import this into Pagedraw.
You'll see this very soon.
But if you ever have a question about what Pagedraw is doing,
you can just look at this and see, for example,
this is a props dot list dot map.
It's iterating over all of the list items,
and calling each of them item, which means that in this--
I posted a comment about the movie--
instead of calling it text 5, I'm going to call it item dot content.
Because inside of that scope, I have this item element
that was defined there for me.
Again, nothing new here.
I'm just doing this in a visual way in Pagedraw, wiring out those variables.
OK, this is item dot content.
That means I'm going to have to change my object input a little bit,
because it's not just a string anymore.
There is this list called this dot props dot list.
And I have to define it.
Let's actually call it reviews.
This dot props dot reviews is going to be the name of my list.
So I'm going to add a new object input type.
I'll call it reviews.
I'm going to find its type to be list.
And it's a list of objects.
Each object has one content, which is a string.
You can define any type of JavaScript object using this here.
Now we're almost done naming our variables.
Text 3 is the description, so I'm going to call this movie description.
Text 3-- movie description.
So now I have this text, text 5, which used
to be this comment, so I don't really need it anymore.
I'm just going to delete it, although it would be fine to leave it there.
Very cool.
So we're now just done defining all of our variables.
One really cool thing that we can do now is you can click on the artboard.
So again, the components-- select this guy here.
You can also make sure you select the artboard by clicking on the title
up here.
And you can go into stress tester mode.
So stress tester mode is essentially a mode
that lets you stress test your designs.
Stress testing means we're going to see how
it looks like with different data, with different screen sizes,
and all that cool stuff.
So you see here, we've already generated some random data
that we put inside of your design.
May the force be with you.
Yo, Adrian!
It went into all the things that you marked as dynamic before.
And if you click randomize data up here, we change it.
And you can see what happens in a different design.
You can also see how it will look like with different screen sizes.
And you see that this probably does not look like what you would want.
You'd probably want some resizing behavior.
In Pagedraw, when you bring a design in or you draw something yourself,
we don't do any responsive by default. You
have to tell us what you want to do.
So for example, if you want this left-hand side
sidebar to expand all the way, you're going
to have to tell us by clicking on it using
these flexible checkboxes on the right.
So you can specify, for example, that it has a flexible height.
Click on here, and, there you go.
It expanded to the whole screen.
You can do this also to margins and to width,
but there is a very nice button up top called Infer
constraints, where we try to just do our best to infer these constraints of you.
So if you click Infer constraints, it just did something reasonable.
The idea is that you click there, and if something
doesn't look like what you want, you'd probably work around it.
So now that we've inferred these constraints,
you can resize and see if this is kind of what you like.
It looks pretty reasonable.
You could argue for something like, oh, I
want this what did you think aligned with the right comment
because in the original design, they were aligned.
A way to do this is I can always wrap things in blocks
to force them to go on together.
So if I click wrap again, now I have a whole block here.
And if I go back to stress tester mode and click here on the art board,
now if I resize, they're forced to be aligned.
Again, whatever you want in here.
There's a nuance here which is that this is not resizing width
any more, even though if I click on this guy, it does say flexible width.
Because that's what we inferred from before.
Because the parent block takes precedence in terms of flexibility.
So if this parent is not marked flexible and the children are,
you're going to ignore what the children are doing actually.
So if we want this to stretch, we want to mark both the child and the parent
as flexible width, which infer constraints would automatically
do for us again.
Well, there you go.
If I want something like this, I just mark that at flexible.
Cool.
Awesome.
Now, let's actually wire this into our React codebase.
OK, this is the part that's very important.
The idea is, again, I can click Export code.
And I can just copy, paste.
But there is a smarter way.
Because if I'm constantly altering my design,
this copy pasting becomes very bothersome.
So what I can do is I can check this button here,
which says [? should ?] pull and sync from the CLI.
It turns out, we have a Pagedraw command line interface.
And if you'll look at our documentation, you can read all about it here.
And you can just install it by doing npm install dash g Pagedraw CLI.
I already have it installed, so I have to do a couple things.
First one is I have to do create a Pagedraw dot JSON in my root directory.
[INAUDIBLE] run next to the package JSON.
And it just needs one entry.
That one entry is called app, and it just says the name of the app that
I'm working with-- the Pagedraw app--
so we know where to fetch files from.
So the name of my app is up here.
It's called Movie Tutorial.
[? Codes are wrong. ?] Co My app is called Movie Tutorial.
Now that I have this file, I can just say, page draw pull.
And it's going to download and place these desktop HD dot GSX
and CSS all inside source slash Pagedraw, which is our default
directory for placing files.
You can override this by going to the editor and changing file paths.
This is just doing this pull once.
If I wanted to constantly keep syncing, I can say, Pagedraw sync instead.
And it's going to just keep listening for changes in the doc
and keep constantly fetching them and putting them in my file system.
So I just leave this Pagedraw sync here for now.
So I have Pagedraw sync running.
I have NPM start running, which is my local dev server.
So now if we go into app dot js, we can actually
get rid of all this render stuff because Pagedraw is going to do this for us.
And get rid of component 2.
I don't need anymore CSS.
I don't need anymore logo images.
And I can just import.
I'll call this app render.
I could call it banana if I wanted to.
From dot splash Pagedraw slash.
And again, the name of the file is desktop HD.
Desktop HD.
And now my render function becomes just one line, which is really cool.
App render, return.
Awesome.
So if I go here--
bam-- I'm getting errors.
Where are these errors?
Well, app did require the Pagedraw component correctly.
It is returning as app render.
Everything is correct.
But remember that we defined all of those dynamic things,
so this is trying to access this dot props reviews that we defined in there.
But we're never passing down reviews into app render right here.
So I can just say, reviews equals whatever.
And, sorry, you need curly brace just like on mt list.
So there we go.
Now that we have reviews, we have zero comments.
We have essentially undefined for everything else.
So we are rendering the page, it just doesn't have any data yet.
So I already have all this data actually in a different file.
So I'm just going to bring it from there, because this part is not
very interesting.
So this is just again doing the same thing
we were doing before by creating some state with all those variables
that we defined.
And the idea with Pagedraw is that frontend development
becomes a lot more like backend development, where
my job as a developer is to deal with data,
and not at all worry about whether something is blue
or is in the middle of a screen or to the right of the screen.
That should be black boxed away from me.
I just deal with data.
I fetch data from a database.
I create data.
And if some events happen, I change that data.
And that's all my job as a developer should be,
and Pagedraw takes care of doing essentially the painting part for you.
So let's copy all of this in.
I actually just need these guys.
This is title here.
It's actually movie title that I want.
And now I'm going to return to app render, which is pretty stupid.
It's just like passing down all of these state things
into the render function like we did before.
So this title image source, it has a few other things
that I'm going to add later, like this comment being typed.
I'm going to add all of these later.
Let's just focus on the stuff that we have so far.
App render, and I need to finish with backslash [INAUDIBLE] syntax.
Reviews, movie, year, director.
I call that actually Movie Title instead of title.
Now reviews doesn't exist.
Reviews is supposed to exist.
Oh, yeah, I didn't bring the reviews.
Reviews.
And again, reviews is a list of a bunch of objects with that content.
Now I just decided that actually I wanted the
write a comment to not go down there.
And probably this image is stretching in a weird way.
So I can always go back to Pagedraw.
And the cool thing now, because I have Pagedraw Sync running,
is if I do some change where I decide, for example, that this big block
doesn't exist anymore, and I want these two to be separated, I just delete it.
And it should already refresh automatically, and there you go.
But still my image looks a little bit funky here.
So what I probably want is there is different ways of choosing
how an image is going to fit the block.
So instead of stretch, I'm going to say, contain,
which I think in this case is going to be a little bit more sane.
There you go.
This looks better.
OK, so we have an app that just knows how to paint things on the screen.
And this is all done by Pagedraw.
It's real cool if I want to change the color here, I just click here,
and it's already going to reload and change there.
Very cool.
So the idea is that Pagedraw takes over our render function.
Now our job is just to do some state mutations.
The last part that we need to do is make this actually dynamic,
where this comment thing.
I can't really type here or add any comments yet.
And I can't do the star functionality.
So let's do the comment idea first.
So in React, because everything is state,
first we have to turn this into a text input, so the user can type.
So right now, this is some text, because we imported it from Sketch.
And this is just text there.
So I'm going to change the block type into text input.
And the placeholder's going to be your comment.
And again, an unstyled text input.
It just comes with some default styles.
I'm going to say it has 0 border, and its fill color
is completely transparent.
And if I check in my Sketch file, I'm pretty sure that the size of the font
was 18.
Yep, 18.
So I'm just going to type in 18 for the font size.
I would like that to be aligned to the left, just like the Sketch file,
so you can actually click on, Use custom padding, and padding [INAUDIBLE] 0.
There we go.
Now this is an actual text input.
If I go to my React app, I can type in here.
Oh, the color is dark.
I probably don't want that.
Let's do something like white for the text color.
Cool, that's what I want.
But just typing here doesn't do anything yet.
It doesn't really add anything to my reviews array,
because we're not doing any state mutations.
So the way that React does this is a little bit interesting
and a little bit different for some people
who are coming from an not React background.
So the idea is right now, we're violating
the React fundamental paradigm.
Why is that?
We are violating the React paradigm because you
see that something is changing on the screen when I type here.
But there is no state changing.
And this is basically going against what React is.
Because the idea is that, again, it should be a pure function.
That every time you have the same state, you
should get the exact same painting of the screen.
But right now, we have one state.
We didn't change that at all.
And we have different paintings when I'm typing something here.
So the first thing I have to do is I have to turn this into some state,
so I can refer to it later to basically fetch this comment.
So the way to do this is, well, I'm going to first, in my code,
add some comment being typed state that starts as nothing, starts empty.
And I'm going to pass it down to app render just like everything else.
Comment being typed equals this dot state dot comment being typed.
And now I just have to use this in Pagedraw
to say that that's what going to be the value in there.
The way to do this is on the sidebar, in the same way
we did D for dynamic earlier, I can actually
hover over a bunch of these things, like placeholder,
and I get this little icon right there that says, Make dynamic.
So I can make anything in Pagedraw dynamic,
like the font size, the font color, the background color, whatever you want.
In this case, I want to make the value, which
is the text that's going to be inside of this text input dynamic.
As soon as I make something dynamic, and now if I go to the code sidebar,
I actually get a new text input value that needs some variable to go in here.
And be highlighted in red for you, so you know that it's empty.
But now there's going to come from this dot state R this dot props [INAUDIBLE]
dot comment being typed.
If I reload my React app, and now if I try to type here--
oh, it's changing.
It's shouldn't.
Let's see.
So I'm trying to type here, it does not let me type.
Why is this happening?
Because now we're not breaking the React paradigm anymore because now
we have a state that comes into the value of this text input.
The state is comment being typed is empty.
And never do I say comment being typed changes.
So that's why you never see any comment here,
which is kind of interesting and kind of unintuitive
for people coming to React at first.
This is a really powerful idea--
this idea of state should define completely what your screen looks like.
So now I need to add an event handler that every time someone types
a letter, say A, it should change comment being typed from nothing to A.
The way to do this is in Pagedraw, you can
click on any block to define event handlers as draw sidebar.
At the end, you see this array here of event handlers?
You can just click Plus, and say whatever event handler you want.
And we just support all the React event handlers.
You can go to React if you want to see all of the event handlers.
They're basically wrappers on top of the browsers' event handlers.
So instead of on click, I'm going to do actually on change.
And here, I'll just say the name of the function that I want--
this dot props dot on change comment.
I just chose the name of the function.
So now let's actually implement this.
I can get rid of the on click me that we were using earlier,
and just say, on change comment.
And I'll actually just copy this from here, so I don't forget the syntax.
This is very simple.
The idea is that every time there is an on change event happening,
I get that event.
I take its value.
And I update using this [INAUDIBLE] state, the comment
being typed to be that new value.
And that's all it is.
This is standard React, by the way.
This is nothing Pagedraw specific.
Pagedraw just allows you to attach these React event handlers to things.
This is the exact same thing that you'd be doing
if you were just using normal React.
And again, the idea of Pagedraw is that Pagedraw does not
change your React work flow basically.
It just fits right into the render function.
All the rest should look exactly like it would look like.
Your backend, your event handlers, your state management
should look exactly like without Pagedraw, but with React.
That means we don't import any like weird libraries.
We're just importing React here, which is really important to note.
OK, on change comment then.
Now we get back to where we were where if I type something--
I should probably refresh--
oh, yeah, I never passed it down to the app render component.
So on change comment equals this dot on change comment.
And I have to do that weird bind this again,
so I have access to the this keyword, instead of this function.
Now I can type again.
But this time, it looks exactly the same as before.
But every time I type something, we're actually
updating the internal react state, which is a huge deal.
Because now, we can actually access this this dot
state dot comment being typed anywhere we want,
which is what we want to do next.
The idea is that whenever we click on this plus button here,
we want to query what is the comment being typed and add it to this list.
Let's just do that right now.
I will first make this blue icon in Pagedraw have a cursor.
So whenever someone hovers over it, it's going to be different,
like a pointer thing.
Let's see.
There you go.
That's just a style thing.
And I'm going to attach an event handler.
This time in on click.
That does this dot props dot on add comment.
And again, I'm making these up as I go.
So add comment.
I'm going to copy this in again.
But it's pretty straightforward.
And it's on add comment is what I called it.
And I'll pass it down to the component just
like I did before. on add comment this dot on comments dot [? bind ?] this.
This function is pretty straightforward.
All it's doing is, it's updating the reviews, or state.
And maybe if they have a real app, it should be like go into the database
and changing that entry.
The database right now, we just have things in memory
and this big [INAUDIBLE] array, which is fine.
And it's concatenating to the this dot state dot comment being typed into it.
So it's getting these new reviews, and then it's setting the state of reviews
to be new reviews.
And it also sets the state of comment being typed to be nothing.
If we don't do that, we would add it to the reviews list,
but you wouldn't essentially erase what you
were typing, which would be slightly awkward from a user perspective.
So now if we go back to our app, you can type, Hello CS 50, and click, Plus.
And I think I didn't refresh.
Hello, CS 50.
Something is happening.
Want add comment on add comment.
I have three Ms in comment.
I think I just spotted the bug.
Thank you very much, Dan.
I think my problem from before is that I was passing on add comment
with three Ms. That is totally my bad.
OK, I think now things should be working hopefully.
So now, let's first test the other one.
Click here.
There we go.
Sweet.
So now the props, if you get the names right--
which I didn't-- whenever you click on this,
that function's going to be called which is going to set the state of a new
reviews list, which is what we wanted.
Hey, this is working.
But now we just got two event handlers that are hopefully working.
That was one.
And if I now click on this guy, it changes the movie.
I didn't change the title.
It's still Monty Python because I'm setting the states to this title,
but I actually used the name Movie Title in this example.
So let's refresh, make sure that works.
So click on that.
It goes to another one of my favorite movies.
And again, this is just attaching event handlers.
And the event handlers are implemented outside of Pagedraw in good old React,
which is just JavaScript.
[INAUDIBLE] console dot log anymore.
Now remember that I set an event handler here when I was debugging.
I'm just going to delete that.
I don't want that part to do on add comment anymore.
And every time you're in a good state, let's say we're in a good state
right now, we like this.
You can commit.
You see up here we say we have uncommitted changes.
So if you select a doc by unselecting any block on the screen,
you see all of my commits previously here.
And I can say, good state for CS 50.
Yay, Include commit.
This way, if someone screws up your doc, changes something, oh, my god, I just
lost everything.
You can click, Restore, and it's going to go back to your good state.
So we're happy about that.
Another a little thing that just showed up and some people
get confused by is if you have two blocks overlapping in Pagedraw,
we show red lines, like that, to basically alert you
that if you have overlapping blocks, we can do them if you want.
We're just going to have to do position absolute in CSS,
which might not be what you want.
So we warn you to see if you really want that.
And often, when you bring Sketch files in, if they're not super polished,
they often come with these things.
Because in Sketch, it doesn't really matter if you have things overlapping.
So one of the steps is also to fix all of those overlapping things,
just so you know to look for it in this.
Now the last thing I want to do is implement this little star component
widget right here.
And again, I just want to have like a rating,
and let the user select the rating.
And notice that we have three states that the star can be in.
Either this is a state of hovering-- the blue one-- this is a state of unfilled,
and this is a state of filled.
So in order to do this in Pagedraw, in order to do this in code,
you do it with an if essentially, where you say, if this is filled,
like do something here.
In Pagedraw, you do what we call multistate component.
So again, you can create components in Pagedraw.
And we use them either in Pagedraw or in your outside code.
The way you create a multistate component is
you select the three or four or five or two
or whatever you want states, and click, make multistate
So this created this multistate group up here that has three art boards.
It's a little bit awkward because the background colors are not the same.
Let me copy this background color right here.
Because you can't see the star because the background color is white,
and the stars are also white.
This background color is just being ignored because it's transparent.
So I'm going-- so we can see the star.
There you go.
You can also see the star here.
The other one I can already see.
So now we created these three states for you inside of the multistate group.
And now these three things are all instances of this component.
And if you want to create instances of this component, what you can do
is now you just click, Add, and add here.
You can add all art board stacks, rectangles,
all of these primitives in Pagedraw.
But you can also add your own primitives, which were defined by you.
So desktop HD is, again, one component that you defined.
Because every time you create an art board, you're defining a component.
And multistate group is another such instance that you can create.
So let's actually create desktop HD to see what that looks like.
This one is going to be big, so I'm going to put it here.
This is not going to be useful very much as a component,
because I don't want to reuse this anywhere.
But it can be useful as a preview.
So right now, you see that the props here
are the ones that we defined earlier.
And I can just click, Generate random props,
where it just fills them up for me.
But I can change the movie title to whatever I want--
Pulp Fiction-- if I want to.
And here, this is another way to have a preview
without having to go back and forth.
If you want, you can just stay in Pagedraw [? and not ?]
have this preview.
More interesting is cases of components that are not previews is actually embed
an instance inside of another component, which we're already doing automatically
for these three guys.
But we didn't do it for the other two guys because we never selected them.
So I'm going to create.
I can do this either by adding or by copy, pasting these guys.
So I'm going to copy, paste this star, and replace the other star with it.
And I'm going to paste another one, and replace this last star also with it.
now notice that all of these guys automatically--
because we created it as a multistate component--
already have an input prop--
prop and input should be the same thing for you--
called state.
And I can choose to go between default state 1 or state 2.
You can change those names later if you want.
So right now, I'm going to state 1, which is unfilled.
And this one is also going to be state 1.
Now if we go to our React app, you should see that reflected there.
But still there is no functionality.
So I want two things.
I want one, hovering should make it blue.
Two, I need to have a rating that defines which of them are filled
or not.
Hover is very easy with Pagedraw.
You can just call the state that you want hovered its name.
sometimes it's hard to select a block.
It selects a different one when you click here.
You can use the layer list to select the exact block that you want.
In this case, I'm selecting the art board called state 2.
And you can click here to change its name to state 2 colon hover.
This is going to make Pagedraw automatically pick this up and make it
hover state, where now, if we go here--
bam-- it's ready.
Whenever I hover, I already see the blue star.
The final thing I want to do is have a variable called ratings.
Again, I don't want to have one variable for each of the stars.
I just want to have one rating, which is a number from 0 to 5.
And then, I'll translate that into whatever each of the stars
is filled or not filled.
So first thing, in my constructor, I'm going
to add my final variable here called rating.
And it's going to start as 3.
And I'm going to pass it in.
Everything that I'm passing in here is so I
can have access inside of Pagedraw.
Because you have to think of Pagedraw as your render function.
This dot state dot rating.
That's all I need here.
And in Pagedraw, if I click on each of these guys,
you see that they have a state.
And I can trigger between the states.
But states also can be made dynamic, which
is what I want to do here, because these states are going to be
dynamic based on their rating variable.
So I'll click here, and make it dynamic.
I'm going to make all of them dynamic.
2, 3, 4, and 5.
Now if I go to the code sidebar, you should
be able to guess now we have five code inputs to fill up,
one for each of the stars.
And this is essentially saying, what is the Boolean
that is going to define the state?
This has to return some state here.
And a state is a string that is essentially the name.
Default versus state 1.
You could change those names if you wanted to.
But I'm not going to right now.
So I'm going to say that this guy--
well, the first one.
The first one is this.
So this dot props dot rating greater than zero.
If that's true--
I'm using a [? ternary ?] operator here--
do state 1, else do default. Now I'll do the same thing for each of these,
but with different ratings.
So this guy is 0, 1, 2, 3.
This guys is 2.
This guy is 1.
And this guy is 4.
So now this is essentially returning either state 1 or default,
depending on what my rating is.
And this is weird.
I think I did the opposite.
This dot props dot rating greater than 1.
I'll do state 1.
Oh, yeah.
I actually wanted default as filled.
So I got this backwards.
Sorry.
State 1-- we'll copy, paste again.
2, 3, 0, and 4.
Let's see now.
There you go.
So 3 is the rating.
If I change my rating here in the constructor to 1,
it should hopefully reflect in my app to be 1 star-- perfect.
Now the final bit is that if I click on a star, I want to change the rating.
By now, you already know how to do that.
The way to do it is to attach an on click handler to each of these stars,
very simple.
So my on click handler--
again, in the draw sidebar here, I can do event handler on click.
This one is going to be a little bit more interesting than the others,
because I can't just say this dot props dot set ratings
or something like that because I need to know what to set ratings to.
And it depends on which star it is.
I could have five functions for each of the stars,
but that will be kind of not ideal.
So what I want to do is actually have a function that wraps this thing here.
That syntax is just wrapping into our function.
Again, anything here can be arbitrary JavaScript, just like in
[? the codes. ?] Although you can put arbitrary JavaScript in there,
and it's going to work.
we don't advise you to put a lot of JavaScript in there.
Just keep it simple.
So this is wrapping into a function, so I can
do this dot props dot set rating to 1.
And I'll copy, paste this, add more event handlers, on click.
These are props I'll set rating 2.
And I'll just do the same thing for all of them.
So that's rating 3, on click.
There you go.
So set rating 4.
Rating 5.
now I need to implement the separating function.
Turns out, I already have it implemented here.
Set rating n this, very simple.
I'll show you in a second.
Set rating n just sets the state of rating to be n, very straightforward.
And now the last bit.
If you've been following, you know we have
to pass it into our render function.
Set rating equals this dot set rating dot find this.
There you go.
Now if I click on any star, it changes the rating.
Awesome.
So there we go.
This is our React plus Pagedraw app.
We can click on stars.
We can change the movie.
There's only two movies right now, but you can imagine having a lot more.
And you can add comments to your movies.
This movie is awesome.
And it's working.
Very cool-- I hope this made sense to all of you.
So now a few questions, a few follow ups on top of what we just talked about.
First one is if you're a CS50 student, you're probably thinking about,
OK, I just learned Python and JavaScript.
And now there's this React things, and how does this all tie together?
And it's an interesting idea how to link time together, like the Python stuff
that you guys did in your problem sets to this context.
Because in here, we do not have any back hand.
So we don't have any Python running or anything like that.
We just have a very simple app that just has frontend.
And the state is living in the front end here.
What we probably want is a database that has
some backend on top of it, which could be in Python,
could be in Ruby, whatever you want.
And it is a this dot state.
Instead of just having these static values, in this JavaScript,
you'd actually talk to the server.
So you have a bunch of what we call endpoints,
or an API, where you talk to the server by querying, what is the current movie
that the user is seeing?
And if the user adds a comment, you go into and say,
hey, database, please update this.
So there's a little bit of work that you do of the JavaScript
here using Ajax and technologies like that
to connect this code to your backed that you probably have.
The idea here is that Pagedraw does not have anything to do with this,
neither does React, frankly.
This is just JavaScript.
And it's kind of up to you how do that as you see fit.
Some follow up questions.
So again, if you've been following, and you
want to do the exact same this demo that we did today,
you can go to pagedraw.io, and just click on Login.
You get redirected to a Google sign in, and you can just
sign in with any g-mail account.
But you might find it more helpful to go to documentation.pagedraw.io.
That's where we explain a lot of the stuff that I've been explaining.
We have references to the React page as well, Pagedraw CLI, this tutorial,
which I'm going to update with the Sketch file
that I just used here as well.
And again, automating frontend development--
a lot of people think it's good for building static landing pages.
As you guys have hopefully seen, it's actually
good for building dashboards, and many things as complicated
as like the Facebook news feed, which we have done in Pagedraw.
As a matter of fact, Pagedraw itself is done
in Pagedraw, which is kind of cool.
So this editor, for example, I can show you guys, we also did in Pagedraw.
This part here that you see in the top bar is exactly implemented here.
You see there's a multistate component.
And each of these calls a component called
Topbar button that also has multistates which has three states-- active, hover,
and so on.
There's this list to add things right here.
And you see it right in here.
So you can, in fact, use Pagedraw to create as complicated [INAUDIBLE]
as you can imagine.
And a very good question before is if you
want to use some functionality from other React components,
you can always do that override code to add custom components as you see fit.
Now some FAQs.
What if Pagedraw doesn't support something I want to do?
Well, I just talked about how using custom components.
The idea is that Pagedraw should support basically
everything HTML and CSS supports.
Although, some of it is kind of hidden right now.
And we're working to make that interface more clear
and to add more things to the documentation.
Probably the most important button in Pagedraw
today is this little button right here.
If you click here, and you can type whatever message,
you can talk to me or to any of us working in Pagedraw right now.
And we'll help you with whatever problem you have.
This has been super useful for a lot of people
building apps with Pagedraw and React.
So we have some support for where you want to do.
But if you really don't, you always have a way
to do all you want by doing custom components using override code.
Right
Second question-- can I manually edit the code that Pagedraw exports?
Should also be pretty clear by now, but the answer is no.
As we've seen with Pagedraw Sync, we keep syncing.
And that code that we exported should be treated as a black box,
except in some debugging cases, which actually we're
building some stuff on top of Pagedraw to also help
you debug these things, which would probably have caught my comments
with three Ms earlier today.
But yes, you can not manually edit the code.
Because if you do manually edit the code,
we're going to have Pagedraw Sync on top of it.
And the next time you export, it's going to override all of your changes
that you manually did.
Can I collaborate with friends on the same project?
For sure, especially for CS50 final projects.
This is a great setup.
You can work with your friends, because this is all live collaborated.
So you can go here to the dashboard, and add collaborators to your project.
And everyone can go into the same dock and actually edit it live,
kind of similar to Google Docs style where multiple people are collaborating
together.
If you want support for other frameworks, languages, and some cool
not so tested features, like Angular, Vue.js, or some backend languages
as well, like Python Jinja, we do have that.
Although, it's hidden behind config flags.
So you can email us at team@pagedraw.io.
And we can set you up if you want to do that.
Getting help, this is really useful.
We can help you on React, Pagedraw, JavaScript,
whatever you're having trouble with.
There's a Facebook group.
You can just follow this.
We'll hopefully post these slides online afterwards,
where people help themselves.
And then there, team@pagedraw.io documentation website
that I showed you guys.
And of course, that little message button
right here, which is really useful.
Finally, if you're interested in Pagedraw,
if you're interested in making web development better
and you are looking for a job, you can also always email us.
We're hiring full-time engineers or designers,
and that's basically it for now.
If you're a full-time engineer or a designer and you're interested,
definitely email us at jobs@pagedraw.io.
Based
There you go.
Thank you very much.
I hope you guys enjoyed this.
And I hope you guys use Pagedraw and React to build awesome things.
Thank you very much.