专栏名称: 众成翻译
翻译,求知的另一种表达
目录
相关文章推荐
白鲸出海  ·  百度完成对YY直播的收购,Anthropic ... ·  16 小时前  
海外独角兽  ·  OpenAI 都在用的 AI 招聘,2 ... ·  17 小时前  
阿里开发者  ·  select `*` from table ... ·  20 小时前  
白鲸出海  ·  中国互联网出海一周头条 ... ·  2 天前  
51好读  ›  专栏  ›  众成翻译

ReactJS Components: 基础指南

众成翻译  · 掘金  ·  · 2018-05-31 09:18

正文

创建和管理React组件的各种方式,涌现的大量状态管理工具等等都是这些挑战的焦点。我们今天能做的就是在React(基于社区选择)中将最常用的做法引入桌面并讨论它们。

其中,我们将学习React中的一些有用的主题和术语。这些主题包括:

目录

  • 常规的Component
  • Props 验证
  • Component之间的交互
  • 初始化Component
  • ES6+ Components (与正常组件有所不同)
  • 无状态组件
这篇文章是很基础的,所以你可能会发现自己正在阅读你已经知道的东西。如果您正在寻找更高级的主题,您可以阅读我们的 其它关于React的文章

常规的 React Component

按照常规,我的意思是常见的,你可能在大多数代码库和文章中看到过:

var Hello = React.createClass({
  render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

请记住,常规并不意味着最佳实践。 React官方文档推广它的原因,只是因为它很常见。

React.createClass函数必须在Object类型的参数中传递。这个对象定义了一个react组件。 render属性是必需的,也是最重要的属性。它负责解析JavaScript, JSX 中的HTML。

Web应用程序只有在动态时才有意思。任何UI库都会提供一种方法来传递系统的数据,React的想法是通过props object来传递数据。所以当你看到下面的JSX时:

<h1>My name is {name}</h1>

我们告诉React,当组件被调用时,带有值的name属性应该像上面例子中的render一样传递:

<Hello name="World" />

渲染方法需要一个组件输出和DOM输出。这是一个React组件的基本解剖。

相关课程: React入门

States & Props

动态应用程序必须将数据传递给系统。在React中,数据移动主要发生在提供原始数据的组件和外部服务之间(例如HTTP,localStorage)。

Props是不可改变的,这意味着它们只能从父组件传递下来,不能改变。这提出了一个挑战,因为现代web程序不可能在页面加载的时候就准备好所有的数据。 Ajax或其它事件也有会可能发生都有可能引发数据的变更,当数据返回时,数据就需要更新。这就是引入React状态地方。

在初始化React时,我们定义一个初始状态并保持state与props同步。一旦state更新,props可以很容易地保持同步:

var Counter = React.createClass({
    getInitialState: function() {
    return {
        counter: 0
    };
  },
  render: function() {
    return <div>
            <h2>{this.props.name}</h2>
            {this.state.counter}
      </div>;
  }
});

ReactDOM.render(
  <Counter name={'Counter'} />,
  document.getElementById('container')
);

父组件

这非常直截了当。如果组件在其render中渲染另一个组件,则渲染器是渲染的所有者(父级)。渲染器拥有渲染的组件并控制它。

我们来看看另一个例子:

var CounterDisplay = React.createClass({
    render: function(){
    return <div>{this.props.counterProp}</div>
  }
})

var Counter = React.createClass({
    getInitialState: function() {
    return {
        counter: 0
    };
  },
  render: function() {
    // Child component rendered
    // React will throw an error if the the DOM doesn't have a single parent
    return <div>
            <h2>{this.props.name}</h2>
            <CounterDisplay counterProp={this.state.counter}></CounterDisplay>
      </div>;
  }
});

ReactDOM.render(
  <Counter name={'Counter'} />,
  document.getElementById('container')
);

Counter现在呈现另一个组件CounterDisplay。 Counter负责管理和同步CounterDisplay的props。您可以看到我们如何通过props将state传递给子组件。这些props也可以像state一样命名为计数器,但这可能会让初学者感到困惑,所以我给了它一个不同的名字。

组件交互

如果我们在子组件中有一个按钮(或更多)来增加或减少在父组件中管理的整数(状态),该怎么办?我们做什么?

React组件交互有两种形式: 从父到子组件的数据流 以及从 子到父的数据流 。我们已经看到了如何通过使用 props 实现父组件对子组件的数据流动。

为了在React实现 子组件对父组件 之间的数据传递,我们使用通过父组件传递给子组件的处理程序作为props, 父组件知道这样的活动可能发生在子组件身上,因此它为发生变化时设置了一个处理程序。更像事件:

// 子组件
var CounterDisplay = React.createClass({
    render: function(){
    // Calls the handler props once events are fired
    return <div>
            <div>{this.props.counterProp}</div>
        <button onClick={this.props.incrementCounter}>+</button>
        <button onClick={this.props.decrementCounter}>-</button>
        </div>
  }
})
// 父组件
var Counter = React.createClass({
    getInitialState: function() {
    return {
        counter: 0
    };
  },
  handleIncrement(){
    // Update counter state
    this.setState({counter : this.state.counter+1});
  },
  handleDecrement(){
      // Update counter state
    this.setState({counter : this.state.counter-1});
  },
  render: function() {
    // Pass down handlers to CounterDisplay component
    return <div>
            <h2>{this.props.name}</h2>
            <CounterDisplay 
            counterProp={this.state.counter}
          incrementCounter={this.handleIncrement}
          decrementCounter={this.handleDecrement}></CounterDisplay>
      </div>;
  }
});

ReactDOM.render(
  <Counter name={'Counter'} />,
  document.getElementById('container')
);

CounterDisplay 组件点击的时候,他们的处理function不在该组件的任何位置,相反,处理程序由父组件Counter处理。该处理程序反过来使用this.setState()方法更新状态,并且计数器显示(子组件)props得到更新

初始化Component

不仅state有能力使用getInitialState方法重新设置初始值。如果需要,您还可以为将在组件负载上使用的props设置默认值。为了达到这个目的,你可以使用getDefaultProps方法:

getDefaultProps: function() {
     return {
       name: 'Counter'
     };
},

这对于在应用程序中设置默认值非常有用。

Prop 验证

关于React组件的一个好消息是,我看到开发人员喜欢并且强调它的可用性。您可以将任何组件放在应用程序中,只要您遵守它的规则,就可以执行它旨在执行的操作。当制作我自己的可重用组件时,我该如何制定自己的规则? Props验证 是你的问题的答案。

按名称进行验证有助于您确信流入组件的数据按照您期望的组织结构进行组织。用户不能将你设置为数组的数据,用字符串传进来。这就是用法

var CounterDisplay = React.createClass({
    render: function(){
    // Calls the handler props once events are fired
    return <div>
            <div>{this.props.counterProp}</div>
        <br />
        <button onClick={this.props.incrementCounter}>+</button>
        <button onClick={this.props.decrementCounter}>-</button>
        </div>
  },
  // Setup validation for each props
  propTypes: {
    // Must be a number
    counterProp: React.PropTypes.number.isRequired,
    // Must be functions
    incrementCounter: React.PropTypes.func.isRequired,
    decrementCounter: React.PropTypes.func.isRequired
   }
})

如果您所需要的只是验证类型,而不是它是否存在,您可以忽略isRequired:







请到「今天看啥」查看全文