ReactJS Components: 基础指南

更新日期: 2018-06-01阅读: 3.1k标签: Component

创建和管理react组件的各种方式,涌现的大量状态管理工具等等都是这些挑战的焦点。我们今天能做的就是在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:

propTypes: {
    // Should be a number
    counterProp: React.PropTypes.number,
    // Should be functions
    incrementCounter: React.PropTypes.func,
    decrementCounter: React.PropTypes.func
   }


Class Component (ES6)

React.createClass并不是创建有效React 组件的唯一可能方法。使用ES6(这真的很酷),我们可以使用clsaa来创建react组件。

// Extends React.Compoent
class Comment extends React.Component {
 // Render method now a class member rather than
 // object property
  render(){
    return <h1>{this.props.name}</h1>;
  }
}

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

组件的名称是类名,class继承React.Component的功能。


在class里面设置state

如果你使用ES6的方法来构造组件,那么设置state的方法也会有一些改变;

class Comment extends React.Component {
   constructor(props) {
        super(props);
        this.state = {
            counter: 0
        };
  }
  render(){
    return <h1>{this.props.name}</h1>;
  }
}

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

初始状态现在在class构造函数中设置,而不是使用getInitialState。


在class中初始和验证props

// Validation
Comment.propTypes = {
        counterProp: React.PropTypes.number.isRequired,
    incrementCounter: React.PropTypes.func.isRequired,
    decrementCounter: React.PropTypes.func.isRequired
};
// Defaults
Comment.defaultProps = {
    name: 'Counter'
};

还有一些细微的差异,但以上是你应该注意的。你可以阅读关于差异的文章 。


无状态组件

当组件没有处理任何状态时,那么您可以使用这些功能:

function CommentDisplay(props) {
  return <div>
            <div>{props.counterProp}</div>
        <br />
        <button onClick={props.incrementCounter}>+</button>
        <button onClick={props.decrementCounter}>-</button>
        </div>
}

就是这么简单!


原文链接: scotch.io  
译文出处 :  zcfy.cc


链接: https://fly63.com/article/detial/846

javascript字符串进行编码的方法:escape编码、encodeURI编码、encodeURIComponent编码

js对字符串进行编码的方法。ECMAScript v3 反对使用escape方法,用 encodeURI() 和 encodeURIComponent() 替代它。encodeURI对URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的。

使用纯粹的JS构建 Web Component

Web Component 出现有一阵子了。 Google 费了很大力气去推动它更广泛的应用,但是除 Opera 和 Chrome 以外的多数主流浏览器对它的支持仍然不够理想。Web Component 是一系列 web 平台的 API,它们可以允许你创建全新可定制、可重用并且封装的 HTML 标签,从而在普通网页及 web 应用中使用。

从VantComponent 谈小程序维护

在开发小程序的时候,我们总是期望用以往的技术规范和语法特点来书写当前的小程序,所以才会有各色的小程序框架,例如 mpvue、taro 等这些编译型框架

react如何通过shouldComponentUpdate来减少重复渲染

在react开发中,经常会遇到组件重复渲染的问题,父组件一个state的变化,就会导致以该组件的所有子组件都重写render,尽管绝大多数子组件的props没有变化

react中的element、component、instance的理解

在React中无论是class形式(render函数)还是function形式(return的内容)的组件,最后返回的jsx其实质是React.createElement函数的结果,而React.createElement函数返回的结果是一个对象树,我们可以称之为元素描述树

React中PureComponent 和 Component区别

我们来看一看 Component 和 PureComponent 的区别,我们先从问题出发,通过解决实际的问题来查询出 PureComponent 和 Component 之间区别。这里创建 Greeting 的组件,其中我们用 setInterval 每间隔 2 秒就更新状态title一次

如何评价 Vue 的 Function-based Component?

react 的不可变,纯函数。直接导致 hooks 必须使用 const 关键字,不能是 let,这也是 hooks 的奇迹之一;Hooks对Fiber更好 -> Hooks是Fiber的产物 -> 没有Fiber就不是Hooks

React Server Component 可能并没有那么香

前段时间 React 团队发布了一项用于解决 React 页面在多接口请求下的性能问题的解决方案 React Server Components。当然该方案目前还在草案阶段,官方也只是发了视频和一个示例 demo 来说明这个草案。

Vue.js 中使用defineAsyncComponent 延迟加载组件

使用 Vue 3 的 defineAsyncComponent 特性可以让我们延迟加载组件。这意味着它们仅在需要时从服务器加载。这是改善初始页面加载的好方法,因为我们的应用程序将以较小的块加载,而不必在页面加载时加载每个组件。

Web Components中引入外部CSS的8种方法

开发中,还是会遇到需要引入外部CSS到Shadow DOM情况,那么如何处理呢?作者就最近遇到的情况给出如下几种方案。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!