class: center, middle # intro to react.js --- # goal to learn software through mentorship and hands-on instruction. remember! * Every question is important * Help each other * Have fun --- # intros to us * Who are you? * What do you hope to get out of the class? --- # knowledge: * javascript * es6 * HTML/CSS # resources: * a codepen account * a text editor * google chrome with react developer tools --- # agenda * day 1 - Hello World! Components, Props, State, JSX, ES6 * day 2 - ES6, Inline Styles, form basics * day 3 - Best practices, more on forms * day 4 - Overview of Redux React --- # resources * [react docs](https://reactjs.org/docs/hello-world.html) * [react tutorial](https://reactjs.org/tutorial/tutorial.html) * [codecademy course](https://www.codecademy.com/learn/react-101) --- # what is react? * The v in mvc * developed by facebook and open-sourced --- # when to use react? * for dynamic sites * if you want to use vanilla JS and ES6, rather than learn a new DSL (domain specific language) --- # getting started with jsx * what is jsx * JSX allows us to describe our User Interfaces (UIs) in a syntax very similar to the HTML * it is optional * JSX provides syntactic sugar for the React.createElement(component, props, ...children) function * you can catch more template errors at compile time, rather than on page load * Making smaller, reusable components is also easier * [jsx](https://jsx.github.io/) * why is jsx * key - React asks for a key attribute that points to a unique ID for each list element * To optimize list display performance * Synthetic events - Some event handlers (onSubmit, onClick) have different names or implementations in different browsers. * The HTML created by your code will be browser specific- simplifying cross browser compatibility. --- # behind the sceans ## Transpiling * babel to transpile it to the supported JavaScript that the browser will understand. * babel can convert the code from ES6 to ES5, this is because not all the browsers can interpret our ES6 ## Virtual DOM * the virtual DOM (VDOM) is a programming concept where an ideal, or “virtual”, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM. * updating the DOM requires browser manipulation, which is slow * updating the virtual DOM does not change the browser (making it faster) --- # behind the sceans ## javascript class * a class is a new Javascript feature, added in ES6 (ECMA2015). * behaves similarly to classes in object-oriented languages. * a class can have a constructor function, which is run on initialization. * a class can extend another class with the "extends" keyword. * If it does so, it's constructor needs to use the word super(). --- # components * components are the building blocks of react * A function component is the simplest form of a React component * It is a simple function with a simple contract ```javascript const Button = (props) => { return (
a simple button
); } ``` * A class component is a more featured way to define a React component * It also acts like a function that receives props, but that function also considers a private internal state ```javascript class Button extends React.Component { state = { counter: 1 }; render() { return (
{this.state.counter}
); } } ``` * [read more](https://reactjs.org/docs/components-and-props.html#functional-and-class-components) --- # code * [open the codepen](https://codepen.io/jks8787/pen/YOvZQQ) * we have function component and a class component ```javascript const Hello = () => (
Hello World
); ``` ```javascript class App extends React.Component { render() { return (
Greetings Earth
); } } ``` * we update the DOM, using a diff of the virtual DOM. * First argument is new HTML, second is the element to insert it in. ```javascript ReactDOM.render(
, document.getElementById('root')); ``` --- # more info on components * props * props are attributes passed down from one component to another * a component's props can be accessed through this.props in the render function * functions can be passed down as props as well. * [open the codepen](https://codepen.io/jks8787/pen/ZMjoNz) * setState * setState() enqueues changes to the component state * this is the primary method you use to update the user interface in response to event handlers and server responses. * [open the codepen](https://codepen.io/jks8787/pen/yxqEPY) * state * state is set at the parent component, and then can passed down to children as props. * a component's initial state is set in the constructor function. * [open the codepen](https://codepen.io/jks8787/pen/aajGgZ) --- # es6 - Object.assign * Object.assign is new to Javascript with ES6. * It takes the first object (usually empty) and then updates it with attributes from any following objects, in order * This is a great way to create new objects based on existing ones concisely * [read more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) # es6 - arrow functions * Arrow functions are a new, improved syntax for functions * One benefit of using arrow functions is that they do not define their own `this`, so you don't need to use `var that=this` with them anymore * [read more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) [open the codepen](https://codepen.io/jks8787/pen/yxqEPY) --- # (legacy) lifecycle hooks * [open the codepen](https://codepen.io/gaearon/pen/vXdGmd) * componentWillMount: * function called before component is rendered. * this is the most commonly used lifecycle hook (AJAX calls, timers) * componentDidMount: * function called after component is rendered. * useful for third party integrations if really needed (plugins) * componentWillUnmount: * function called before component is removed from the DOM * componentDidUnmount: * function called after removal from DOM. * Useful for cleanup (removing timers, etc.) --- # (current) [lifecycle hooks](https://twitter.com/dan_abramov/status/981712092611989509?lang=en) * constructor(props): * the first method called during mount is the constructor * this should be used to initialize the local state, or any other variables, and bind methods. * getDerivedStateFromProps(props, state): * created to "replace" componentWillReceiveProps * updates the state before rendering * is a static method it doesn’t have access to the component instanc * to update the state just return a plain object, or null * serves the same purpose as setState(), but it runs earlier in the lifecycle --- # (current) [lifecycle hooks](https://twitter.com/dan_abramov/status/981712092611989509?lang=en) * render(): * is the only required method in a React Component * called for the first time during mount * used to render DOM nodes * componentDidMount(): * last method called during the mounting phase * can fetching asynchronous data, handling subscriptions or binding event handlers * can also callsetState() --- # (current) [lifecycle hooks](https://twitter.com/dan_abramov/status/981712092611989509?lang=en) * shouldComponentUpdate(nextProps, nextState): * method used to intercept the update lifecycle * compare your current props and state to the next ones * then based on the comparsion decide to rerender or not. * getSnapshotBeforeUpdate(prevProps, prevState): * this runs after the render * reads the most recent DOM changes, before they are applied --- # (current) [lifecycle hooks](https://twitter.com/dan_abramov/status/981712092611989509?lang=en) * componentDidUpdate(prevProps, prevState, snapshot): * similar to componentDidMount, but runs every time an update occurs * changes to the DOM are already committed * can change the state using setState() * should wrap it in a condition * changes to the state triggers a new update * componentWillUnmount(): * called when the component is about to be destroyed * to clear timeouts, stop network requests --- # composition vs inheritance * composition is always preferred over inheritance in React - make components as reusable as possible! * [docs](https://reactjs.org/docs/composition-vs-inheritance.html#so-what-about-inheritance) --- # controlled components * [docs](https://reactjs.org/docs/forms.html) ``` In HTML, form elements such as
,
, and
typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with setState(). ``` * [open the codepen](https://codepen.io/gaearon/pen/VmmPgp?editors=0010) --- # uncontrolled components * [docs](https://reactjs.org/docs/uncontrolled-components.html) * use refs to store internal form state, and use setState on submit * use defaultValue to set initial values in form elements (input, select, etc.) * usually not recommended if you can use controlled components (or Redux) * [open the codepen](https://codepen.io/gaearon/pen/WooRWa?editors=0010) --- # suggested reading/coding * [thinking in react](https://reactjs.org/docs/thinking-in-react.html) * [simple react todo list](https://medium.com/@aghh1504/1-simple-react-todo-list-52186b62976b) * [embracing es6 part1](https://cantina.co/embracing-es6-part1/) * [ES5 vs ES6 ( With example code )](https://codeburst.io/es5-vs-es6-with-example-code-9901fa0136fc) * [use ecmascript 6 today](https://code.tutsplus.com/articles/use-ecmascript-6-today--net-31582) * [react tutorial](https://reactjs.org/tutorial/tutorial.html) --- # agenda * day 1 - Hello World! Components, Props, State, JSX, ES6 * day 2 - ES6, Inline Styles, form basics * day 3 - Best practices, more on forms * day 4 - Overview of Redux React --- # review * jsx --> javascript that looks like HTML, and gets compiled to javascript that renders HTML * props --> attributes passed down from one component to another; a component's props can be accessed through this.props in the render function * state --> Data stored in parent component, passed down to child components through props; Initialized in the constructor function; Updated with this.setState * this.state and this.props are immutable * react tutorial [solution](https://codepen.io/gaearon/pen/gWWZgR) --- # review * functional components - For child components where you only need the render function ```javascript const Button = (props) => { return (
a simple button
); } ``` * A class component is a more featured way to define a React component * It also acts like a function that receives props, but that function also considers a private internal state ```javascript class Button extends React.Component { state = { counter: 1 }; render() { return (
{this.state.counter}
); } } ``` --- # review * lifecycle hooks * [docs](https://reactjs.org/docs/react-component.html#mounting) * composition vs inheritance * [docs](https://reactjs.org/docs/composition-vs-inheritance.html#so-what-about-inheritance) --- # review * forms! * [docs](https://reactjs.org/docs/forms.html) * [controlled component codepen](https://codepen.io/gaearon/pen/VmmPgp?editors=0010) && [uncontrolled component codepen](https://codepen.io/gaearon/pen/WooRWa?editors=0010) ```javascript class NameForm extends React.Component { constructor(props) { super(props); this.state = {value: ''}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { ... } handleSubmit(event) { ... } render() { return (
Name:
); } } ``` --- # create a todo app ( in code pen ) * [skeleton todo app](https://codepen.io/jks8787/pen/OooXzy?editors=0110) * [todo app finished with data from api](https://codepen.io/jks8787/pen/gddMob) ```javascript function Checkbox(props) {...} function InputText(props) {...} function NewTodo(props) {...} function TodoContainer(props) {...} function TodoList(props) {...} class TodoApp extends React.Component { ... render() { return (
); } } ``` --- # create an app with create react app * `Create React apps with no build configuration.` (yay!) ```bash npm install -g create-react-app create-react-app my-app cd my-app npm install npm start ``` --- # setting up your app * you can now move your code from codepen into the new app * each component could be it's own file * use import and export statements to do this * [suggested folder structure for react](https://reactjs.org/docs/faq-structure.html) * [create-react-app folder structure](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#folder-structure) * you can add tests * create-react-app comes with jest * [running tests](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#running-tests) * you can add styles per component * [adding a style sheet](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-stylesheet) --- # suggested reading/coding * Start working on your own React project :) * a personal site * a blog * a game * advanced resources ( redux or mobx ) * [getting started with redux](https://egghead.io/courses/getting-started-with-redux) * [manage-application state with mobx state tree](https://egghead.io/courses/manage-application-state-with-mobx-state-tree) --- # agenda * day 1 - Hello World! Components, Props, State, JSX, ES6 * day 2 - ES6, Inline Styles, form basics * day 3 - Best practices, more on forms * day 4 - Overview of Redux React --- # review * todo app in code pen * [initial todo app](https://codepen.io/jks8787/pen/OooXzy?editors=0110) * [todo app with more components](https://codepen.io/jks8787/pen/gddMob?editors=0110) ```javascript function Checkbox(props) {...} function InputText(props) {...} function NewTodo(props) {...} function TodoContainer(props) {...} function TodoList(props) {...} class TodoApp extends React.Component { ... render() { return (
); } } ReactDOM.render(
, document.getElementById('root')); ``` --- # review * todo app in with create react app * `Create React apps with no build configuration.` (yay!) ```bash npm install -g create-react-app create-react-app my-app cd my-app npm install npm start ``` --- # adding up your app * keep working on your todo app * [open code sandbox](https://codesandbox.io/s/5vw3m6o8o4) * [adding to test setup with enzyme](https://github.com/airbnb/enzyme) * [add a CSS preprocessor](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-css-preprocessor-sass-less-etc) * [add a router](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-router) * [add some images](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-images-fonts-and-files) * [fetch data for todos](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#fetching-data-with-ajax-requests) --- # redux overview * [docs about redux's motivations](https://redux.js.org/introduction/motivation) ```bash Managing this ever-changing state is hard. When a system is opaque and non-deterministic, it is hard to reproduce bugs or add new features. ``` * [docs about redux's eco system](https://redux.js.org/introduction/ecosystem) ```bash Redux is a tiny library, but its contracts and APIs are carefully chosen to spawn an ecosystem of tools and extensions, and the community has created a wide variety of helpful addons, libraries, and tools. ``` --- # redux overview * [docs about redux's three principles](https://redux.js.org/introduction/threeprinciples) ```javascript Single source of truth * The state of your whole application is stored in an object tree within a single store. State is read-only * The only way to change the state is to emit an action, an object describing what happened. Changes are made with pure functions * To specify how the state tree is transformed by actions, you write pure reducers. ``` --- # suggested reading/coding * [a cartoon intro to redux](https://code-cartoons.com/a-cartoon-intro-to-redux-3afb775501a6) * [when should I use redux](https://redux.js.org/faq/general#when-should-i-use-redux) * [you might not need redux](https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367) * [Replacing Redux with the new React context API](https://medium.freecodecamp.org/replacing-redux-with-the-new-react-context-api-8f5d01a00e8c) --- # redux in practice * Adding Redux to a React App * install packages ```bash npm install --save redux react-redux redux-thunk ``` --- * Adding Redux to a React App * setting up files and folders * [docs about code structure](https://redux.js.org/docs/faq/CodeStructure.html#code-structure) ```bash Just to get us started we will get the ball rolling with a little bit of setup. First you will want three directories, ./actions , ./reducers , ./store all in the src directory of the app. ``` * Essentially actions describe something happening, and the reducer responds to the action. * [docs about reducers](http://redux.js.org/docs/basics/Reducers.html#reducers) * [docs about actions](https://redux.js.org/basics/reducers#actions) * [docs about the store](https://redux.js.org/basics/store) --- * Knitting it together * actions up, data down * we call an action from our component * that action returns its value * based on the type a case is triggered in the reducer * a new state is returned --- # Thanks! ---