Stanford CS142 笔记 - How React Works

For how to use React to create a Web Application, including how to create component, props, and states, please refer to MIT Weblab笔记 - React Introduction and MIT Weblab笔记 - React Advanced.

Takeaway

  • To create a React application, we first define a React.js Web Application Page, then define a root React component (like <APP />), and then render the root React component into browser DOM.
  • JSX maps to calls to React.createElement.
  • A React component can be defined as a function, and the states are managed by hooks.
  • When I first type a url and hit enter, I send a http request to the server. Since this is the initial connect, the server responds a index.html file, which is the entry of the web application, as well as a bundle.js file, which is generated by Webpack (According to a configuration file webpack.config.js). Webpack takes all my project’s JavaScript, along with other assets (like CSS, images, or even other files), and bundles them into one or more output files that can be served to the browser. Then browser executes bundle.js. This is where the app’s frontend logic starts running.

Create a React Application

React.js Web Application Page

1
2
3
4
5
6
7
8
9
10
<!doctype html> 
<html>
<head>
<title>CS142 Example</title>
</head>
<body>
<div id="reactapp"></div>
<script src="./webpackOutput/reactApp.bundle.js"></script>
</body>
</html>
  • the div element with the ID “reactapp”: serves as the “root” of the React application, where the entire React component tree will be rendered. Essentially, when the application runs, React will take control of this div and dynamically update the content within it based on the application’s state and logic.
  • bundle.js: The script tag is used to include the JavaScript file that contains the bundled React code. The file bundles all the React components, JavaScript, and other assets into a single file (or multiple files) for efficient loading and execution in the browser.
  • When the script is loaded, it uses the DOM API to render and update the view inside the div with ID reactapp.

Render elements into browser DOM

1
2
3
4
5
6
import React from 'react';
import ReactDOM from 'react-dom';
import ReactAppView from './components/ReactAppView';
let viewTree = React.createElement(ReactAppView, null);
let where = document.getElementById('reactapp');
ReactDOM.render(viewTree, where);
  • viewTree: creates an instance of the ReactAppView React component
  • where: the DOM element with the ID “reactapp”
  • ReactDOM.render: This is the key function that tells React to render the viewTree (which contains the ReactAppView component) into the where element, which is the div with the ID reactapp define in the previous React.js Web Application Page. This effectively “mounts” the React component into the browser’s DOM.

Define ReactAppView component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React from 'react';

class ReactAppView extends React.Component {
constructor(props) {
super(props);
this.state = { yourName: "" };
// Binding handleChange method in the constructor
this.handleChange = this.handleChange.bind(this);
}

handleChange(event) {
this.setState({ yourName: event.target.value });
}

render() {
let label = React.createElement('label', null, 'Name: ');
let input = React.createElement('input', { type: 'text', value: this.state.yourName, onChange: (event) => this.handleChange(event) });
let h1 = React.createElement('h1', null, 'Hello ', this.state.yourName, '!');
return React.createElement('div', null, label, input, h1);
}
}

export default ReactAppView;
  • constructor: initialize the component’s state or bind methods. In this case, this.state is an object that contains key-value pairs representing the component’s state.

  • render(): The render() method is required for any React component. It defines what the component should output to the DOM. This method returns a React element or a tree of elements.

  • react.createElement(): const element = createElement(type, props, …children).

    • type: HTML tag or React Component
    • props: attributes
    • children: can be String or numbers, React element, or an array of the above
  • this.setState is a method provided by React’s Component class to change the state.

  • The above code renders the following HTML Structure:

1
2
3
4
5
<div>
<label>Name: </label>
<input type="text" ... />
<h1>Hello {this.state.yourName}!</h1>
</div>

We can use JSX to concisely define the component output to the DOM instead of using react.createElement():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
constructor(props) {
super(props);
this.state = { yourName: "" };
// Binding handleChange method in the constructor
this.handleChange = this.handleChange.bind(this);
}

handleChange(event) {
this.setState({ yourName: event.target.value });
}

render() {
return (
<div>
<label>Name: </label>
<input
type="text"
value={this.state.yourName}
onChange={this.handleChange}
/>
<h1>Hello {this.state.yourName}!</h1>
</div>
);
}
  • JSX maps to calls to React.createElement.

  • Writing in JavaScript HTML-like syntax that is converted to JavaScript function calls.

  • when this.handleChange is called from the event, the “this” keyword inside handleChange function might not refer to the component instance (ReactAppView), so “this” in this.setState({ yourName: event.target.value }) of handleChange function might cause errors. As a result, we use this.handleChange = this.handleChange.bind(this): binding the “this” context of handleChange to the component instance.

We can use arrow functions (Arrow functions inherently bind this to the surrounding context at the time of their definition):

1
2
3
handleChange = (event) => {
this.setState({ yourName: event.target.value });
}
  • In this case, we can avoid bindding “this” in the constructor.
  • Everytime handleChange is called, the “this” keyword inside this function refers to the object of the class.

A more concise component definition:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React from 'react';

class ReactAppView extends React.Component {
constructor(props) {
super(props);
this.state = { yourName: "" };
}

handleChange = (event) => {
this.setState({ yourName: event.target.value });
}

render() {
return (
<div>
<label>Name: </label>
<input
type="text"
value={this.state.yourName}
onChange={this.handleChange}
/>
<h1>Hello {this.state.yourName}!</h1>
</div>
);
}
}

export default ReactAppView;

Stateless Components and React Hooks

A React component can be defined as a function if it only depends on props. Previously, we define React component by defining a class that extends React.Component.

1
2
3
function MyComponent(props) {
return <div>My name is {props.name}</div>;
}

Before hooks, functional components were “stateless.” With hooks like useState, we can now add state to these components.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, { useState } from 'react';

function Example() {
const [count, setCount] = useState(0);

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

React.js Tool Chain

Sample Image
  • Each React component is passed through Babel, a popular JavaScript compiler, which transpiles JSX and ES6+ into a version of JavaScript that is compatible with all browsers.
  • The transpiled components are then bundled together by Webpack.
  • bundle.js: This bundled file is what actually gets loaded in the browser, and it contains everything your React application needs to run.

Webpack can bundle all of your project’s files (JavaScript, CSS, images, etc.) into a single file. It enables us to do like following:

1
2
3
4
5
6
// app.js
import { add } from './math';
import { logResult } from './utils';

const result = add(5, 10);
logResult(result);

Now we only need to include one script in the HTML, otherwise, we need to manually include all script files.

1
<script src="bundle.js"></script>

Stanford CS142 笔记 - How React Works
https://thiefcat.github.io/2024/08/12/CS142/How-React-Works/
Author
小贼猫
Posted on
August 12, 2024
Licensed under