$ ls ~yifei/notes/

学习 React

Posted on:

Last modified:

前端框架是 UI = fn(state) 这种声明式的思想,只需要声明组件的视图、组件的状态数据、组件之间 的依赖关系,那么状态改变就会自动的更新 dom。而 jquery 那种直接操作 dom 的工具函数库则是命令式的。

什么是前端 App

除去 UI 组件外,至少还需要 State 和 API 两个库

App := Router + UI + State + API

Router := Next.js
UI     := React
State  := valtio
API    := swr + axios

当我第一次接触前端的时候,那时候流行的是后端 MVC 模式。过去写界面的方法是,把所有的结构 (html),动作 (js),样式 (css) 分开,好处是非侵入,离了谁都能工作,缺点是无法模块化。在 js 无足轻重,甚至有 noscript 这种插件的过去,显然 MVC 是最佳实践,但是到了 js 大行其道的 今天,把 html/js/css 打包在一起的模块化又被提出来了。

react 中也没有模板中的 {% block xxx %} 这个概念,直接使用 props。

Hello World

ReactDOM.render(
  <h1>Hello, world!</h1>,
 document.getElementById('root')
);

Jsx 中可以使用大括号插值。对于 html 中不能自闭合的标签,都可以自闭合。JSX 最终会被编译成 JavaScript.

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

// 相当于
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

一个函数就可以是一个组件。在 React 16 时代,就不要再用 class 了,统一用函数式组件就好了。

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

// 相当于
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

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

props 只有向下传递一种方式。所有的函数都必须是纯函数。使用函数作为组件的一个缺点是没有办法保存状态。

在 class 组件中,需要使用使用 setState 更新状态。不能使用 += 类似的操作符,setState 是异步的,因此要传递回调函数。

事件

react 的事件和 HTML 的不同。所有属性是 camelCase 的;不能通过 return false 来阻止事件,必须调用 e.preventDefault

<button onClick={activateLasers}>
  Activate Lasers
</button>

一般情况下,在 React 中是不需要调用 addEventListener

条件渲染

React 是 functional 的。所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。state 是组件内部的状态。

key 是一个很关键的概念,有点像是 html 中的 ID, 用来唯一标示一个元素,因为 react 会尽可能 复用元素。key 不需要是全局唯一的,只需要在兄弟元素之间唯一即可。

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

const numbers = [1, 2, 3, 4, 5];

ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

组合

在 React 中不要使用继承来组织组件,而要使用组合,这也是近几年来面向对象领域的趋势。在 React 中,可以通过读取 props.children 来获取传递进来的子组件。

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>
  );
}

如果需要对子组件布局的话,可以使用命名的方式:

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  )
}

function App() {
  return <SplitPane left={ <Contacts /> } right={ <Chat /> } />
}

另一种方式是特化,也就是类似函数的 partial

Thinking in React

React 设计哲学:https://zh-hans.reactjs.org/docs/thinking-in-react.html

  • FilterableProductTable
    • SearchBar
    • ProductTable
      • ProductCategoryRow
      • ProductRow

已经过期的一些知识

由于 JS 的 this 的坑,需要使用 public class fields。如果要向回调函数中使用参数需要这样:onClick={(e) => this.deleteRow(id, e)}

class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.
  // Warning: this is *experimental* syntax.
  handleClick = () => {
    console.log('this is:', this);
  }
render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

如果需要传递参数的话:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>

参考资料

  1. https://medium.com/@Zwenza/functional-vs-class-components-in-react-231e3fbd7108
  2. https://segmentfault.com/a/1190000011474522
  3. https://stackoverflow.com/questions/22876978/loop-inside-react-jsx
  4. 前端框架发展史
  5. 跨端开发简史
  6. 前端架构对比
WeChat Qr Code

© 2016-2022 Yifei Kong. Powered by ynotes

All contents are under the CC-BY-NC-SA license, if not otherwise specified.

Opinions expressed here are solely my own and do not express the views or opinions of my employer.

友情链接: MySQL 教程站