# 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
组成,单向数据流,显式突变,仅基于 JavaScriptYou 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 应用程序,所有的事件驱动,只是监听事件和直接修改 DOMRemember 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
这使突变变得明确
- 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 语法,尽管通常使用 JSXJSX 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 placeJSX 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”,道具应为一个对象
- If you are not passing props use
# 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 DOMReactDOM.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 orclass
based
React 组件可以是基于函数的,也可以是基于类的React component names should start with a capital letter
Optionally input via props are passed into thefunction
orclass
React 组件名称应以大写字母开头(可选)通过 props 输入并传递到函数或类中A component always returns a
React element
组件总是返回一个 React 元素How do you decide if you want to use a
function
orclass
?
如何决定使用函数还是类?- 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.
如果组件需要保存组件中的任何数据或状态,则需要使用类并将数据保存在组件状态中。
- If your component needs to save any data or state within the component, you need to use a
# 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 throughprops
.
如果有很多需要状态的组件,则应该创建一个包含状态的父组件,并通过 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 特别有用。
# 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
<!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> |
<!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
The File API does not allow you to directly read or write files anywhere on the users hard disk.
When importing an ES module it is possible to rename what you are importing using a different name.
React components must be defined as a Class.
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.
The web storage API allows you to only save strings in localStorage.
In React, you must use the
setState()
method to update state in a component.The HTML Canvas API rotate transform will rotate the grid before you draw something.
In React, you have to initialize state in a class components constructor.
When using the web storage API you must use the
setItem()
method to save a value in a storage key.Which HTMl Canvas API method would you use to draw a circle?
React components must return a React element.
It is required to use the type=“module” attribute on a script tag if you are using ES modules in that code.
Babel is used to compile JavaScript into machine level code.
Where is the 0, 0 point on the HTML Canvas API grid?
The IndexedDB API is a SQL based database in the browser.