了解State、Props,学会React
发布于 7 年前 作者 Tonyce 4851 次浏览 来自 分享

State Props——React的关键所在

原文《State Props——React的关键所在》

只有 State,Props,仅此而已。

React 只有 State(状态)、Props(属性),仅此而已。就是这么简单。所以说,如果你会 JS,也了解了 State(状态)和 Props(属性)。那么就可以你已经掌握了 React 大部分知识了。

在 State,Props 之前,先来看一下 React 的基础。

JSX

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

This funny tag syntax is neither a string nor HTML.
It is called JSX, and it is a syntax extension to JavaScript.

const element = <h1>Hello, world!</h1>;这样的表达式就是 JSX 。它是 JavaScript 语法的延伸。

在 JSX 中,允许将 JS 代码和 HTML 标签一起使用。这样就可以使用熟悉 JS 来展开逻辑,使用熟悉的 HTML 来呈现 UI。不过这里有一点,就是一个 JSX 只能有一个根节点。所谓一个根节点,就是 HTML 最外面有且只有一个 HTML 标签。

const element = (
  <div>
    <h1>Hello<h1>
  </div>
  <h1>world!<h1>
)

像这样就是错误的,因为在最外面有和 div 同级的 h1。

const element = (
  <div>
    <h1>Hello<h1>
    <h1>world!<h1>
  </div>
)

改正的话,只需要将外面的 h1 移到 div里面,确保最外层只有一个 HTML 标签就好了。为什么要这样呢?因为这是 React 构建 **虚拟DOM(tree[树])**的需要。不知道虚拟DOM是什么鬼?不知道Tree[树]?没关系,我也不知道。后面会有 React 虚拟DOM 的介绍。现在只需要记住这个规则就好了。

JSX 和 Typescript

如果使用 Typescript 来写 React,那 JSX 就相应的转变成了 TSX,其实本质还是不变的。

const element: JSX.Element = <h1>Hello, world!</h1>;

可以看到,element后面多了个类型,叫 JSX.Element。我们看到的 React 应用 UI,都是通过 JSX.Element 映射到 HTML 上的。什么叫映射?额。。。这里可以当是呈现理解。

Component

**什么是 Component(组件)?**对于 React 来讲(对Vue、Angular也一样),Component(组件)就是构成 React 的零件。如果把一个 React 应用比作你手中的电脑的话。那么主机、显示屏、键盘就是这个应用的组件。当然,主机这一大的组件还可以分成其它的较小的组件–CPU、主板等。主机、显示屏、键盘等其它零件有效的拼凑在一起,就形成了你手中的电脑。React 应用也一样,也通过一个或多的组件的合理组合。所以,Component 也相当于 React 应用的零件。

在 Component 的生命周期中有一个重要的方法:render。生命周期?会在下一篇中介绍。

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

render 中返回的 HTML 就是该 Component 在UI上要呈现的样子。所以,编写 React Component的最终目的,就是通过逻辑,来控制 render 的返回结果。

JSX 是语法支持,Component 是理论支撑。那如何使 Component render 我们想要的 UI,那就需要涉及 Component 的两个重要概念:State、Props

Props(属性)

属性就是一个事物的所属性质。对于不同事物,属性所代表的也有可能不一样。这里也只说 React Component 的 Props。

React 中,Component 的 Props 都是 Component 对其外部环境的变量的持有或引用。Component 所持有的 Props,并不能被其本身所改变,而相反的,若是 Component 所持有或引用的 Props 改变,那 Component 就要根据 Props 的变化,而做出相应的变化。

看一个例子(TodoApp)

class TodoApp extends React.Component {
  ...
  render() {
    return (
      ...
      <TodoList items={this.state.items} />
      ...
    )
  }
  ...
}
class TodoList extends React.Component {
  render() {
    return (
      <ul>
        {this.props.items.map(item => (
          <li key={item.id}>{item.text}</li>
        ))}
      </ul>
    );
  }
}

在这个例子中,items 就是 TodoList 的 Props。items 的改变就会引起 TodoList 这个组件的改变。

这个例子有没有很熟悉的感觉。TodoList 是不是很像 HTML 中的自定义标签。与 HTML 标签是一样的,写法都是一样的。你会HTML,会JS,你就会 React!

在 Component中,可以通过 this.props(this.props.items)直接拿到相应的 Props。是不是比 HTML 标签还要简单。

State(状态)

React 中,State(状态)就是对 Component 自身的描述。对于 Component 来讲,Props 是外界叫它怎么样它就怎么样,Component 是对 Props 没有控制力的。而 State 不一样,Component 对 State 是有绝对控制力的。不受外界干扰,就是老子想怎么样就怎么样。

这里我们也可以看到 React 的设计哲学:影响事物发展的无非就是外因内因,而 Props 和 State就是 Component的外因和内因。

在 Component,是这样定义 State 的

class TodoApp extends React.Component {
  constructor(props) {
    ...
    this.state = {items: [], text: ''};
  }
  ...
  render() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <input onChange={this.handleChange} value={this.state.text} />
          <button>{'Add #' + (this.state.items.length + 1)}</button>
        </form>
      </div>
    );
  }
  ...
}

在代码中,可以看到,state是被 TodoApp Component所完全持有的。Component 可以通过改变自身的 State (setState()) 来改变 render 中逻辑。进而呈现不同UI。

State、Props 和 Typescript

使用 JS 写的 Component,Props 和 State表现的并不明显。虽然有 Flow 的解决方案。但 Typescript 的解决方案会更优雅和高效。

使用 Typescript 编写 React 组件,需要为组件定义好 Props 和 State。而这也被证明是个好的编码方式。可以帮助你构建更健壮的APP。至少是帮助了我。

...
interface OwnProps {
}

interface OwnState {
}

class TodoApp extends React.Component<OwnProps, OwnState> {
  ....
  render(): JSX.Element {
    return <div></div>
  }
}

这样的代码结构可以使我们快速的知道 TodoApp 这个 Component,拥有什么样的Props,和什么样的State。代码变得更加清晰和紧凑。更利于对团队开发和维护。

感觉写了一锅粥🤦‍

原文《State Props——React的关键所在》

9 回复

然而,我现在还是很会,估计我js也不会

现在的react应用层state估计都写在了redux了吧

redux 现在是 rn 项目的标配了,不过,我还是不懂它是怎么用的 😂

@lipoipoi 这个还是视具体情况使用得好

@liygheart Redux管理根组件的 State,子组件的 Props

@liygheart 可以试试用mobx,redux不是必须的选择

回到顶部