惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
WordPress大学
WordPress大学
Microsoft Security Blog
Microsoft Security Blog
GbyAI
GbyAI
V
Visual Studio Blog
The Register - Security
The Register - Security
Y
Y Combinator Blog
I
InfoQ
小众软件
小众软件
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Scott Helme
Scott Helme
C
Cybersecurity and Infrastructure Security Agency CISA
T
Threatpost
Hacker News: Ask HN
Hacker News: Ask HN
P
Privacy International News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
Arctic Wolf
P
Privacy & Cybersecurity Law Blog
AWS News Blog
AWS News Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Check Point Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
Security Affairs
Cyberwarzone
Cyberwarzone
V
Vulnerabilities – Threatpost
C
Cyber Attacks, Cyber Crime and Cyber Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
爱范儿
爱范儿
Spread Privacy
Spread Privacy
Recent Commits to openclaw:main
Recent Commits to openclaw:main
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog
C
CERT Recently Published Vulnerability Notes
IT之家
IT之家
月光博客
月光博客
雷峰网
雷峰网
博客园 - 【当耐特】
Stack Overflow Blog
Stack Overflow Blog
美团技术团队
NISL@THU
NISL@THU
U
Unit 42
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

Whexy Blog

We lost the AIxCC. So, what now? Arm VMM with Apple's Hypervisor Framework Driving WaveShare E‐Paper Display with a Raspberry Pi Pico in MicroPython Use cgroup v2 inside docker containers Annual Hit Piece: Fuzzing Top Conference Paper Debunking Report Solving SSH Key Login Issues on Synology NAS Can SSD Cache Improve Synology NAS Write Speeds? Virtualization is all you need Running Windows Games on Mac Without Virtual Machines Tears of the Kingdom: End of an Era Anonymous CDN Traffic Relay Self-host Relay Service with CDN Home Networking Solution Building Your Own Blog System Connecting Smart Devices to SUSTech Campus Network Function Color Theory Stop Forkin' Around: Faster Creating of Large Processes on Linux PMU Interrupts: How to handle them Asynchronous Mutex Using QEMU to run Linux images on M1 Macbook Alligator In Vest - My first research work Experience Using Several Plugins in Complex LaTeX Projects Variance in Rust Understanding Rust Generic Traits SUSTeam: Ultimate Gaming Platform Inline Assembly Language in C Building a School Bus Schedule App for Apple Watch 12307 Train Ticket Purchase Platform Sakai and Local Folder Synchronization Building a Super Simple OpenJudge in Two Nights Setting Up Remote Backup for macOS Shell Script for Automatically Logging into SUSTech Campus Network Building a Movie Streaming System in the Dorm
React Learning Notes
Whexy · 2020-10-21 · via Whexy Blog

React utilizes almost all the characteristics of native JavaScript. With proficiency in JavaScript, React won't bring you many surprises. However, compared to Vue, writing React also gives a solid feeling.

Notes after reading React Documentation

const element = <h1>Hello, world!</h1>;

JSX is a JavaScript extension. It embeds HTML elements into JavaScript code.

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

React DOM elements are static immutable minimal units maintained by the framework. Therefore React claims its overhead is very small. Since they are immutable units, each page update is actually new elements overwriting old elements.

React combines elements and underlying components, abstracting them into higher-dimensional reusable components.

There are two ways to define components: function components and class components (ES6 Later)

//Function
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
//Class
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

User-defined components require the first letter to be capitalized. Once defined, they can be called directly in JSX.

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(element, document.getElementById("root"));

React gives an example in the documentation showing the benefits of extracting components into multiple small components for program writing. In this example, React suggests naming props from the component's own perspective, rather than depending on the context of the calling component.

Additionally, components must ensure they don't modify incoming props.

Function components are a simpler type of component that don't support other features. When using class components, you can achieve the purpose of storing state by maintaining the class's "member variables."

The following example maintains its own state when the component is mounted. State is a JS object.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = { date: new Date() };
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

However, direct modification of this.state won't be captured by React and thus won't update on the page. Perhaps this is one of the reasons for many negative comments about React?

You need to call the this.setState(object) function to update state. This function has several characteristics:

  1. Updates are asynchronous, so you can't rely on state values to calculate the next state.
  2. this.setState() can accept functions as parameters. This function's first parameter is the previous state, and the second parameter is the component's parameters. Using functions as parameters can solve asynchronous update errors.
this.setState((state, props) => ({
  counter: state.counter + props.increment,
}));
  1. State updates are shallow merges. this.setState(small_obj) won't overwrite other properties outside of small_obj.

Downward Flow

All kinds of GUI drawing languages constantly emphasize one concept — consistency. Frontend often displays and modifies the same data source in different components. For example, after a user changes their username in settings, all places displaying the username need to be updated synchronously. If each component maintains its own update operations, you enter a bug-prone zone.

For example, the iOS frontend framework SwiftUI emphasizes the concept of "Single Source of Truth" everywhere. Although React doesn't have a strict concept of state screening, you can pass the content of state as the next props to child components. React vividly calls this writing style "downward flow."

However, React prohibits any modification of incoming properties. If we want to modify a single data source in child components, we need to call the unique modification function, which is calling the modification function implemented by ancestors holding state (called "reverse data flow" in "Thinking in React"). This is quite troublesome. React claims this is to facilitate bug tracking because data modification has only one entry point.

After a component is placed in the DOM, the componentDidMount() function will be called. When it's about to be destroyed, the componentWillUnmount() function will be called to release occupied resources.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = { date: new Date() };
  }

  componentDidMount() {
    this.timerID = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date(),
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

React element events are similar to DOM elements. Syntactically, React uses camelCase (onClick) and passes a JSX-wrapped function, rather than strings in DOM.

<!-- Traditional DOM approach -->
<button onclick="handler()">A button</button>
<!--  React element approach-->
<button onClick={handler}>
    A button
</button>

You can pass parameters to event handlers.

<button onClick={e => this.handler(id, e)}>A button</button>

Where e is React's event object.

💡

Reference reading: JavaScript's Crucial Apply, Call and Bind

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isToggleOn: true };

    // This binding is essential for using `this` in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn,
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? "ON" : "OFF"}
      </button>
    );
  }
}

There's experimental syntax that can solve this problem. Write the handleClick() function like this:

handleCLick() = () => {
    console.log(this);
}

This way you can call this in the function without explicitly binding this externally. Or you can also write it in JSX like this:

<button onClick={() => this.handleClick()}>A button</button>

React renders elements through function component return values or class component render() functions. Therefore, as long as you use conditional statements in components and return different JSX, you can achieve conditional rendering.

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  // Try changing to isLoggedIn={true}:
  <Greeting isLoggedIn={false} />,
  document.getElementById("root"),
);

It's worth noting that every time you call the setState() function, React automatically re-executes render(). So you can create stateful components like this:

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = { isLoggedIn: false };
  }

  handleLoginClick() {
    this.setState({ isLoggedIn: true });
  }

  handleLogoutClick() {
    this.setState({ isLoggedIn: false });
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

Stateful components can calculate elements to display based on state in the render() function first.

There's also a cooler way to write it:

<div>
  <h1>Hello!</h1>
  {unreadMessages.length > 0 && (
    <h2>You have {unreadMessages.length} unread messages.</h2>
  )}
</div>

In JavaScript, true && express returns express. Conversely, false && express returns false. If it returns false, React will ignore rendering this group of elements.

Of course, ternary operators can also be used for conditional rendering:

<div>
  {isLoggedIn ? (
    <LogoutButton onClick={this.handleLogoutClick} />
  ) : (
    <LoginButton onClick={this.handleLoginClick} />
  )}
</div>

Similar to v-for in Vue, React can also achieve "lazy" repeated component rendering.

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map(number => <li>{number}</li>);
ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById("root"),
);

In the above code, listItems is an array of JSX. React flexibly inserts it into the page.

It's best to bind keys to list elements. This way, React can identify which elements have changed. Keys should be bound in array context. For example, keys are usually set in the map() method.

function ListItem(props) {
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map(number => (
    <ListItem key={number.toString()} value={number} />
  ));
  return <ul>{listItems}</ul>;
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById("root"),
);

As mentioned earlier, React recommends a "downward flow" approach. That is, you can ensure data handled in React comes from the same source. In HTML, form elements usually maintain their own state by browsers themselves. For example:

<form>
  <label>
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

The input box value is maintained by the browser itself. In fact, we can let React take over state, thus achieving the goal of single data source. Form elements taken over by React are called "controlled components."

<form onSubmit={this.handleSubmit}>
  <label>
    Name:
    <input
      type="text"
      value={this.state.value}
      onChange={this.handleChange}
    />
  </label>
  <input type="submit" value="Submit" />
</form>

Tags like input, textarea, select can all be taken over by React.

React recommends using JS syntax for code reuse between components.

Containment Relationship

Recommended approach for component nesting:

function FancyBorder(props) {
  return (
    <div className={"FancyBorder FancyBorder-" + props.color}>
      {props.children}
    </div>
  );
}

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">Welcome</h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

Pass child components to render results through prop.children. If we specify tag parameter names in JSX, we don't need to use children.

Specialization Relationship

React can also design "abstract parent components." "Child components" that implement these components are achieved by passing specific parameters.

© LICENSED UNDER CC BY-NC-SA 4.0