Creating a Movie Review App with React + Pagedraw
We're going to build an interactive movie review app using React and Pagedraw. If you like you can check out the final result here.
We are assuming some familiarity with Javascript. If you're not familiar, we recommend you look at this link
In this video we give a short intro to React, then we move on to productionizing a Sketch design in Pagedraw. If you're already familiar with React, we recommend that you jump straight to 15:00 in the video.
This video covers
- Dynamic data to feed code variables into your design
- Layout constraints to make your design work on multiple devices
- Stress tester to ensure 1. and 2. are working as expected
- Calling Pagedraw generated code from a React app
- Pagedraw syncing with the Pagedraw CLI
- Adding event handlers such as
onClick
andonChange
that call your JS code - Text inputs
- Multistate components
To follow along, download the final code and the Sketch file used in this tutorial here.
Sketch-less flow tutorial
Below you can also find another version of the same tutorial, that does not showcase a Sketch importing flow. Instead, you create the whole UI directly in Pagedraw. This guide assumes some familiarity with React. To read about React, check this link
Part 1: Getting started
In this video you'll install the Pagedraw CLI, create your first Pagedraw drawing, and add a simple onClick
handler that changes the movie image when you click on it.
This part of the tutorial goes over:
- Pagedraw editor basics
- Pagedraw syncing with the Pagedraw CLI
- Layout constraints to make your design work on multiple devices
- Dynamic data to feed code variables into your design
- Adding a simple
onClick
handler that calls your JS code
Simplest Pagedraw example. App
simply calls AppRender
, which is Pagedraw generated.
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import AppRender from './pagedraw/component_1';
import registerServiceWorker from './registerServiceWorker';
class App extends Component {
render() {
return <AppRender />;
}
}
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
At the end of this video, your index.js
should look like
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import AppRender from './pagedraw/component_1';
import registerServiceWorker from './registerServiceWorker';
class App extends Component {
constructor() {
super()
this.state = {
title: 'Pulp Fiction',
img_src: "https://ucarecdn.com/5e0a6047-d3e0-46f4-bbe6-c095fb64996a/"
};
}
render() {
return <AppRender title={this.state.title} img_src={this.state.img_src}
changeMovie={this.changeMovie.bind(this)} />;
}
changeMovie() {
this.setState({
title: 'Back to the Future',
img_src: "https://ucarecdn.com/29b73fb5-8421-46bd-adf0-740793a622a7/"
});
}
}
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Part 2: Components and Multistate Groups
In this video we introduce the powerful notion of components, props, and instance blocks in Pagedraw. We also create a multistate component to implement 5 stars the user can click to rate their favorite movies.
This part of the tutorial goes over:
- Components and Props
- Instance Blocks
- Generating random data for instances
- Multistate components
- More advanced dynamic data piping
In this video you should change the render function from Part 1 to be
render() {
return <AppRender title={this.state.title} img_src={this.state.img_src}
changeMovie={this.changeMovie.bind(this)}
setRating={this.setRating.bind(this)} />;
}
and also add the setRating
method
setRating(n) {
this.setState({rating: n});
}
Part 3: Repeat Blocks and more Event Handlers
In this video we add the classic Todo list example to our movie app. In this case it takes the form of a feature that lets users comment on the movies they like.
This part of the tutorial goes over:
- Repeat blocks
- More advanced Prop types for components
- Adding a text input
- More advanced eventHandlers
At the end, index.js
should look like this
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import AppRender from './pagedraw/component_1';
import registerServiceWorker from './registerServiceWorker';
class App extends Component {
constructor() {
super()
this.state = {
title: 'Pulp Fiction',
img_src: "https://ucarecdn.com/5e0a6047-d3e0-46f4-bbe6-c095fb64996a/",
rating: 0,
reviews: [
{content: 'This is a test review'},
{content: 'Oh hai, world!'}
],
commentBeingTyped: ''
};
}
render() {
return <AppRender title={this.state.title} img_src={this.state.img_src}
changeMovie={this.changeMovie.bind(this)}
reviews={this.state.reviews}
rating={this.state.rating}
commentBeingTyped={this.state.commentBeingTyped}
onChangeComment={this.onChangeComment.bind(this)}
addComment={this.addComment.bind(this)}
setRating={this.setRating.bind(this)} />;
}
onChangeComment(e) {
this.setState({commentBeingTyped: e.target.value});
}
addComment() {
const new_reviews = this.state.reviews.concat([{content: this.state.commentBeingTyped}]);
this.setState({reviews: new_reviews, commentBeingTyped: ''});
}
changeMovie() {
this.setState({
title: 'Back to the Future',
img_src: "https://ucarecdn.com/29b73fb5-8421-46bd-adf0-740793a622a7/"
});
}
setRating(n) {
this.setState({rating: n});
}
}
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();