# Babel

  • Babel is used to convert JSX to plain JavaScript React calls.
    Babel 用于将 JSX 转换为普通的 JavaScript 反应调用。
  • Babel can also compile our ES6+ to ES5
    还可以将 ES6 编译成 ES5
  • Babel can be directly used in the browser for development purposes
    出于开发目的,可以在浏览器中直接使用 Babel
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- Your custom script here -->
<script type="text/babel">
const getMessage = () => "Hello World";
document.getElementById('output').innerHTML = getMessage();
</script>
  • Need to configure the babel presets or it won’t do anything.
    需要配置 babel 预设,否则它什么也做不了。
    Typically in a .babelrc file.
    通常在 .Babelrc 文件中。
  • Need to load modules for the presets you want to use and then add them to the .babelrc
    需要加载要使用的预设的模块,然后将它们添加到 .babelrc
  • https://babeljs.io/docs/setup/#installation

# React JS

# What is React?

  • Created at Facebook by software engineer Jordan Walke
    由软件工程师乔丹・沃克在 Facebook 创建

  • An early prototype in 2011 (FaxJS) shipped as a search element on Facebook. Jordan then worked on a prototype for the hard to manage Facebook Ads which became react.
    2011 年的一个早期原型 (FaxJS) 在 Facebook 上作为搜索元素发布。乔丹随后为难以管理的 Facebook 广告制作了一个原型,后来变成了 Reaction。

  • Deployed in newsfeed in 2011 and instagram.com in 2012 after Facebook acquired them.
    在 2011 年和 2012 年被 facebook 收购后,分别在 newsfeed 和 instagram 上部署。

  • Open sourced at JSConf US May 2013
    2013.05 开源

  • Used to build interactive user interfaces for applications that have frequent data changes.
    用于为数据更改频繁的应用程序构建交互式用户界面。

  • When the components internal data changes it automatically updates the markup.
    当组件内部数据更改时,它会自动更新标记。

  • Can be used to build UI components, single page applications (SPA), and iOS, Android or UWP when using React Native.
    可以用来构建 UI 组件,单页应用程序 (SPA),和 iOS, Android 或 UWP 时使用 React Native。

  • https://en.wikipedia.org/wiki/React_(JavaScript_library)

  • https://reactjs.org/

  • https://facebook.github.io/react-native/


  • A library for building user interfaces.
    用于构建用户界面的库。

  • Composition, Unidirectional Dataflow, Explicit Mutations, Just JavaScript
    组成,单向数据流,显式突变,仅基于 JavaScript

  • You compose a user interface with components
    用组件组成一个用户界面

  • Component Based - Components are encapsulated chunks and manage their own state and can be nested inside each other
    基于组件的 - 组件被封装成块,管理它们自己的状态,并且可以彼此嵌套

  • Component logic is all in JavaScript and there are no HTML templates used
    组件逻辑全部使用 JavaScript,没有使用 HTML 模板

  • Data is passed to the component through properties or props with a one way data flow
    数据通过带有单向数据流的属性或 props 传递给组件

  • Properties or props are a set of immutable values that gets passed to the components render function
    属性或 props 是一组传递给组件呈现函数的不可变值

  • Components should not directly modify the values in props. Instead pass callback functions from the parents via props.
    组件不应该直接修改 props 中的值。而是通过 props,从父函数传递回调函数。

  • Uses a Virtual DOM in the background and only updates the visible DOM when needed, including only updating the parts that need to.
    在后台使用 “Virtual DOM”,只在需要的时候更新可见 DOM,包括只更新需要的部分。

  • Can be used to build single page application or just components on an existing website or web application
    可以用来构建单页面应用程序或仅组件在现有的网站或 web 应用程序

  • It can be directly used in the browser in a script tag or with a bundler to package all the JS files in one big file.
    可以直接在浏览器的脚本标记中使用,也可以通过绑定器将所有 JS 文件打包到一个大文件中。

  • Works well as a node js project. All modules used are typically node modules.
    作为一个节点 js 项目工作得很好。所有使用的模块通常都是节点模块。

  • There is a Create React App node package that will produce a skeleton app as a starting point with a preconfigured build pipeline.
    有一个 Create React App 节点包,它将生成一个骨架应用,作为一个预先配置的构建管道的起点。

  • https://reactjs.org/docs/installation.html

  • https://reactjs.org/docs/react-api.html

# Composition

  • You compose the UI out of multiple components
    用户界面由多个组件组成
<Container>
    <NavBar />
    <Header />
    <DatePicker>
        <Calendar />
    </DatePicker>
    <Footer />
</Container>

# Unidirectional Dataflow 单向数据流

  • In a React app data flows from parent component to child component
    React 应用中,数据从父组件流到子组件

  • Data is passed as props to the component and the props are immutable
    数据作为 props 传递给组件,props 是不可变的

  • If a component needs to save data/state it needs to do that in itself or get that data as props from a parent
    如果组件需要保存数据 / 状态,它需要自己保存数据或从父组件获取作为 props 的数据

  • Props are added to a component as attributes of the component (in JSX) or as the second argument to a createElement() function call
    Props 作为组件的属性 (在 JSX 中) 添加到组件中,或者作为 createElement() 函数调用的第二个参数

  • Different than a normal JS/Jquery app that is all event driven and just listening for events and modifying the DOM directly
    不同于普通的 JS/Jquery 应用程序,所有的事件驱动,只是监听事件和直接修改 DOM

  • Remember Data flows down to the component and is immutable
    记住,数据流向组件,并且是不可变的
    <HeaderComponent name="brian" />

  • If you need to pass data back up the chain you need to pass down a function to run and call that function within the component
    如果需要向上传递数据,则需要向下传递一个函数,以便在组件中运行和调用该函数

# Explicit mutations

  • You will explicitly change or mutate the components state to update the component
    将显式更改或改变组件状态以更新组件

    • This makes mutations explicit
      这使突变变得明确
  • You use the setState() function to trigger this state mutation and pass it the updated state items
    使用 setState() 函数触发此状态突变并将更新后的状态项传递给它

    this.setState({
        name: 'brian',
        class: 'itmd4565'
    })

    Can also pass setState() a function that looks at the known good previous state
    也可以传递 setState() 一个函数,查看已知的良好的先前状态

    this.setState(prevState => ({
        seconds: prevState.seconds + 1
    }))

# JSX

  • Can use an optional JSX syntax in your JavaScript code although typically JSX is used
    可以在 JavaScript 代码中使用可选的 JSX 语法,尽管通常使用 JSX

  • JSX is a JavaScript syntax extension
    JSX 是一个 JavaScript 语法扩展

  • This allows us to use what looks like HTML tag syntax to render our components.
    它允许我们使用看起来像 HTML 标记语法的东西来呈现我们的组件。

  • If we don’t use JSX we need use the React.createElement() function in its place

  • JSX allows you to evaluate JavaScript expressions in your JSX with curly brackets { }

  • Custom HTML attributes are passed in but need to start with data-

  • Since JSX is not supported by browsers or runtimes you need to convert it to plain JS with a tool like babel .

# React Elements

  • Fundamental object and concept in React apps
    React 应用程序中的基本对象和概念
A React element
is a JavaScript object representation that describes how you would like it to appear on the screen.
是一种 JavaScript 对象表示形式,描述希望它在屏幕上的显示方式。
This is a JavaScript representation of a DOM Node.
是 DOM 节点的 JavaScript 表示。
  • Use React.createElement() to create an element

    • All JSX will be converted to React Elements by babel React.
  • createElement(type, [props], [...children])

    const element = React.createElement(
                        'div',
                        {id: 'button' },
                        'Login Now'
                    )
    • If you are not passing props use null , props should be an object
      如果不传递 props,请使用 “null”,道具应为一个对象

# ReactDOM

  • React does not provide a way to use elements in a web page by itself
    React 本身不提供在网页中使用元素的方法
ReactDOM
provides the DOM-specific methods that you can use to interact with the DOM in a web page
提供了特定于 DOM 的方法,您可以使用这些方法与 web 页面中的 DOM 进行交互
  • We use the ReactDOM.render() method to render a React element into the web DOM

  • ReactDOM.render(element, container[, callback]);

    const element = <h1>Hello, world</h1>;
    ReactDOM.render(
        element,
        document.getElementById('app')
    );

# Components

A component
is a function or a Class which optionally accepts input and returns a React element.
组件是一个函数或类,可以选择接受输入并返回 React 元素。
  • React components can be function based or class based
    React 组件可以是基于函数的,也可以是基于类的

  • React component names should start with a capital letter
    Optionally input via props are passed into the function or class
    React 组件名称应以大写字母开头(可选)通过 props 输入并传递到函数或类中

  • A component always returns a React element
    组件总是返回一个 React 元素

  • How do you decide if you want to use a function or class ?
    如何决定使用函数还是类?

    • If your component needs to save any data or state within the component, you need to use a class and save the data in the components state.
      如果组件需要保存组件中的任何数据或状态,则需要使用类并将数据保存在组件状态中。

# Functional Components

  • Stateless functional components can be written as a simple function
    无状态功能组件可以编写为一个简单的函数
function HelloHeader(props){
    return (<h1>Hello World!</h1>);
}

Or

const HelloHeader = (props) => {
    return (<h1>Hello World!</h1>);
}
ReactDOM.render(<HelloHeader />, document.getElementById('app'));

# Create Components

  • Components should be designed as small possibility reusable elements that are added to a react app.
    组件应设计为添加到 react 应用程序中的小可能性可重用元素。

  • Create components as ES6 classes.
    将组件创建为 ES6 类。

  • There was an old deprecated syntax that used React.createClass() instead of ES6 classes but it has been removed.
    有一种旧的不推荐使用的语法使用了 React.createClass() 而不是 ES6 类,但它已被删除。

  • The only required method in the component class is the render() function
    组件类中唯一需要的方法是 render() 函数

  • A basic example is below

class HelloHeader extends React.Component {
    render() {
        return <h1>Hello World!</h1>;
    }
}
ReactDOM.render(<HelloHeader />, document.getElementById('app'));
  • The same basic component is below without JSX
    下面是相同的基本组件,但没有使用 JSX
class HelloHeader extends React.Component {
    render() {
        return  React.createElement('h1', null, 'Hello World!');
    }
}
  • Components can use other components
    组件可以使用其他组件
class HelloHeader extends React.Component {
    render() {
        return <h1>Hello World!</h1>;
    }
}
class Page extends React.Component {
    render() {
        return (
            <div>
            <HelloHeader />
            </div>
        );
    }
}

# Data Flow

  • Data flows from parent to child via properties and are available in the child with this.props .
    数据通过属性从父级流到子级,并且可以在子级中用 this.props 使用。
    And properties are immutable.
    属性是不可变的。
class HelloHeader extends React.Component {
    render() {
        return <h1>Hello {this.props.name}</h1>;
    }
}
class Page extends React.Component {
    render() {
        return(
            <div>
            <HelloHeader name=’Brian’ />
            </div>
        );
    }
}

# Inverse Data Flow – Child to Parent

反向数据流 - 从子数据流到父数据流

  • Pass a parents event handler as a property on the child then in the child call that handler to pass data back to the parent for setting state or something else.
    将父事件处理程序作为属性传递给子程序,然后在子程序中调用该处理程序,将数据传递回父程序以设置状态或其他内容。
class Page extends React.Component {
    render(){
        return (
            <MainHeader />
            <Greeting searchFunction={this.searchHandler}>Hello World!</Greeting>
            <MainFooter />
        );
    }
    searchHandler(e){
        console.log(e);
    }
}

# State

  • State is place we can store data in a component and change the data to see a reflection in the UI.
    状态是可以在组件中存储数据,并更改数据,以在 UI 中看到反射的位置。

  • It is available in the this.state object
    可以在 this.state 对象中找到

  • Must add a constructor to your class and initialize the state there.
    必须为类添加构造函数,并在那里初始化状态。

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            header: "Header from state...",
            content: "Content from state..."
        }
    }
    render() {
        return ( <div> <h1>{this.state.header}</h1> <h2>{this.state.content}</h2> </div> );
    }
}
  • Try to make the state as simple as possible and keep as many components stateless as possible.
    尽量使状态简单,并使尽可能多的组件保持无状态。
    If you have many components that need state you should make a parent component that has the state in it and pass it down through props .
    如果有很多需要状态的组件,则应该创建一个包含状态的父组件,并通过 props 将它传递下去。

  • Do not try to modify the state object directly
    不尝试直接修改状态对象

// Wrong
this.state.comment = 'Hello';
// Correct
this.setState({ comment: 'Hello' });
// Or Correct
this.setState((currentState) => { return new state});
  • If you need to set state in one component from another you need to pass handlers down to the child component that then calls setState() in the parent that has the state object.
    如果需要在一个组件和另一个组件之间设置状态,你需要将处理程序向下传递给子组件,然后子组件在拥有 state 对象的父组件中调用 setState()

  • The React library watches this state and when it detects changes it compares it to the browser DOM and updates only what is necessary
    React 库监视这种状态,当它检测到变化时,它将其与浏览器 DOM 进行比较,只更新必要的内容

# Helpful Array Functions

Here are a few array functions you should know.
下面是一些你应该知道的数组函数。

The important part here is they work in a functional way.
这里的重要部分是它们以一种功能性的方式工作。

They do not modify the input but instead return a new array.
它们不会修改输入,而是返回一个新数组。

Map is especially helpful when outputting JSX from arrays.
当从数组输出 JSX 时,Map 特别有用。

map()

filter()

reduce()

concat()

# React JS Resources

  • https://reactjs.org/
  • https://facebook.github.io/react-native/
  • https://babeljs.io/
  • https://tylermcginnis.com/
  • https://webpack.js.org/
  • https://learn.co/lessons/react-create-element
  • https://www.tutorialspoint.com/reactjs/reactjs_state.htm
  • https://ihatetomatoes.net/react-tutorial-for-beginners/

# DEMO

React Babel Prototyping
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React/Babel In-Browser Prototyping</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> 
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
    <div id="root"></div>
    <script type="text/babel">
        const getMessage = () => 'Hello World!';
        document.getElementById('root').innerHTML = getMessage();
    </script>
</body>
</html>
React fundamentals
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React/Babel In-Browser Prototyping</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> 
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
    <div id="root"></div>
    <script type="text/babel">
        let name = "Brian";
        let email = "bbailey4@iit.edu";
        // React Element - <h1>Brian</h1>
        const nameElement = React.createElement('h1', null, name);
        // React JSX Element
        const nameJSXElement = <h1>{name}</h1>;
        // Stateless functional component
        function NameFunctionalComponent(props) {
            return React.createElement('h1', null, props.myname);
        }
        // Stateless JSX function component
        function NameFunctionalComponentJSX(props) {
            return <h1>{props.myname}</h1>;
        }
        // class component JSX
        class NameClassComponentJSX extends React.Component {
            render(){
                return (
                    <React.Fragment>
                        <h1>{this.props.myname}</h1>
                        <h2>{this.props.myemail}</h2>
                        <h3>{this.props.subject}</h3>
                    </React.Fragment>
                );
            }
        }
        //class component no JSX
        class NameClassComponent extends React.Component {
            render(){
                return React.createElement('div', null, React.createElement('h1', null, this.props.myname), React.createElement('h2', null, this.props.myemail), React.createElement('h3', null, this.props.subject));
            }
        }
        //wrapper component - JSX
        class WrapperClassComponentJSX extends React.Component {
            render(){
                return (
                    <div>
                        <NameClassComponentJSX myname={this.props.name} myemail={this.props.email} subject={this.props.subject} />
                        <NameFunctionalComponentJSX myname={this.props.name} /> 
                    </div>
                );
            }
        }
        // Class Component with State
        class ButtonComponent extends React.Component {
            constructor(props){
                super(props);
                this.state = {counter: 0};
                this.handleButtonClick = this.handleButtonClick.bind(this);
            }
            render(){
                return <button onClick={this.handleButtonClick}>{this.props.text} - {this.state.counter}</button>;
            }
            handleButtonClick(e) {
                console.log('clicked');
                this.setState(currentState => {
                    return {counter: currentState.counter + 1};
                });
            }
        }
        //App Component
        function App(props) {
            return (
                <div>
                    <ButtonComponent text="My Button 1" />
                    <ButtonComponent text="My Button 2" />
                </div>
            );
        }
        //ReactDOM
        //ReactDOM.render(nameElement, document.getElementById('root'));
        //ReactDOM.render(nameJSXElement, document.getElementById('root'));
        //ReactDOM.render(React.createElement(NameFunctionalComponent, {myname: name}), document.getElementById('root'));
        //ReactDOM.render(<NameFunctionalComponentJSX myname={name} />, document.getElementById('root'));
        //ReactDOM.render(<NameClassComponentJSX myname={name} myemail={email} subject='JavaScript' />, document.getElementById('root'));
        //ReactDOM.render(React.createElement(NameClassComponent, {myname: name, myemail: email, subject: 'Javascript'}), document.getElementById('root'));
        //ReactDOM.render(<WrapperClassComponentJSX name={name} email={email} subject="JavaScript" />, document.getElementById('root'));
        //ReactDOM.render(<ButtonComponent text="My Button" />, document.getElementById('root'));
        ReactDOM.render(<App />, document.getElementById('root'));
    </script>
</body>
</html>

# Quiz 7

  1. The File API does not allow you to directly read or write files anywhere on the users hard disk.

  2. When importing an ES module it is possible to rename what you are importing using a different name.

  3. React components must be defined as a Class.

  4. In React, data passed as a prop can be directly edited in the component it was passed to and it will update in the parent component.

  5. The web storage API allows you to only save strings in localStorage.

  6. In React, you must use the setState() method to update state in a component.

  7. The HTML Canvas API rotate transform will rotate the grid before you draw something.

  8. In React, you have to initialize state in a class components constructor.

  9. When using the web storage API you must use the setItem() method to save a value in a storage key.

  10. Which HTMl Canvas API method would you use to draw a circle?

    • quadraticCurveTo()
    • arc()
    • bezierCurveTo()
    • circle()
  11. React components must return a React element.

  12. It is required to use the type=“module” attribute on a script tag if you are using ES modules in that code.

  13. Babel is used to compile JavaScript into machine level code.

  14. Where is the 0, 0 point on the HTML Canvas API grid?

    • Top Left
    • Top Right
    • Bottom Left
    • Bottom Right
  15. The IndexedDB API is a SQL based database in the browser.