Maison > interface Web > js tutoriel > le corps du texte

Tutoriel d'introduction au framework JavaScript React super génial_Connaissances de base

WBOY
Libérer: 2016-05-16 15:51:54
original
1764 Les gens l'ont consulté

React est un framework génial créé par un groupe de codeurs géniaux de Facebook. Un DOM virtuel est implémenté, en utilisant la méthode DOM pour ajouter les composants requis en quelques secondes et supprimer les composants inutiles en quelques secondes. React joue le rôle de V dans la structure MVC, mais si vous l'utilisez avec Flux, vous disposerez d'un framework très génial qui pourra facilement synchroniser M et V. Nous parlerons de Flux plus tard~
Composants

Dans React, vous pouvez créer un composant avec des fonctions spéciales que vous ne trouvez pas dans les éléments HTML, comme la navigation déroulante dans ce tutoriel. Chaque composant a sa propre portée, donc après avoir défini un composant, nous pouvons l'utiliser encore et encore sans interagir du tout avec d'autres composants !

Chaque composant a une fonction appelée render , qui peut renvoyer efficacement du HTML à émettre au navigateur. Nous pouvons également appeler d'autres composants de React, ce qui signifie que React est aussi profond que la mer. Oh, non, il n'y a rien auquel nous ne puissions penser mais rien que nous ne puissions faire.

JSX

Si vous faites souvent attention à React, vous constaterez peut-être qu'il existe quelque chose appelé JSX. JSX nous permet d'écrire du HTML en Javascript, plutôt que du HTML contenant du Javascript. Cela nous aide à nous développer rapidement car nous n'avons pas à nous soucier des chaînes, des sauts de ligne, etc. Vous pouvez exécuter JSX dans le navigateur, mais cela n'est pas recommandé car cela ralentirait votre page. gulp et grunt fournissent un interpréteur JSX pour vos tâches de prétraitement, donc si vous souhaitez utiliser JSX, je vous recommande d'activer cette fonctionnalité.
Utiliser JSX

Comme mentionné précédemment, chaque composant JSX a une méthode de rendu, qui génère un "ViewModel" - avant de renvoyer du HTML au composant, vous pouvez mettre les informations de ce modèle (ViewModel) dans la vue, ce qui signifie que votre HTML changera dynamiquement basé sur ce modèle (comme une liste dynamique).


Une fois que vous avez terminé, vous pouvez retourner ce que vous voulez restituer, c'est si simple avec JSX

var ExampleComponent = React.createClass({
  render: function () {
    return (
      <div className="navigation">
        Hello World!
      </div>
      );
  }
});
Copier après la connexion

Si vous deviez exécuter ce code dans votre navigateur, vous n'obtiendriez qu'une erreur de syntaxe car les caractères < et > Lorsque vous exécutez l'interpréteur JSX sur votre code, il sera converti en quelque chose comme ceci

var ExampleComponent = React.createClass({
  render: function () {
    return (
      React.createElement('div', {className: 'navigation'}, 'Hello World!')
      );
  }
});
Copier après la connexion

Vous pouvez cliquer ici pour tester l'exemple - j'utilise l'interpréteur JSX du navigateur (ce n'est pas recommandé, mais pour le bien de JSFiddle).

Ça roule ! JSX interprète tous les nœuds DOM que vous générez à l'aide de React.createElement, en générant des types de nœuds, des paramètres et du contenu. Vous pouvez vous passer de JSX, mais cela signifie que vous devez écrire manuellement tous les nœuds DOM à l'exception de React.createElement. D'innombrables exemples me disent d'utiliser JSX.

Vous devez vous demander pourquoi j'utilise className au lieu de class sur le DOM. C'est parce que la classe est un mot réservé en Javascript. Lorsque JSX interprète votre code, il modifiera toutes les propriétés de ce nœud en objet, mais vous ne pouvez pas traiter les objets comme des propriétés !

Utiliser des variables sur les attributs
Si vous souhaitez modifier dynamiquement la classe de style du composant (ou toute autre valeur d'attribut), vous pouvez utiliser des variables. Mais vous ne pouvez pas simplement transmettre un nom de variable, vous devez l'entourer d'une paire d'accolades. comme ça, JSX saura qu'il s'agit d'une variable externe.

var ExampleComponent = React.createClass({
render: function () {
  var navigationClass = 'navigation';
  return (
    <div className={ navigationClass }>
      Hello World!
    </div>
    );
}
});
Copier après la connexion

Vous pouvez voir cette fonctionnalité ici.
Rendu initial
Lorsque vous effectuez le rendu initial d'un composant React, vous devez indiquer à React quel composant restituer et spécifier un nœud DOM existant pour indiquer où restituer le composant. Pour ce faire, vous utiliserez la fonction React.render.

var ExampleComponent = React.createClass({
render: function () {
  return (
    <div className="navigation">
      Hello World!
    </div>
    );
}
});
React.render(<ExampleContent />, document.body);
Copier après la connexion

Il rendra le composant sur le nœud body - facile ! À partir de là, vous pourrez appeler d'autres composants comme d'habitude, ou utiliser la fonction de rendu autant de fois que vous le souhaitez, si vous ne souhaitez pas utiliser React pour rendre le composant. page entière mais je souhaite toujours utiliser plusieurs composants.

La base d'un composant

Les composants peuvent avoir leur propre "état". Cela nous permet de réutiliser les mêmes composants plusieurs fois mais de leur donner un aspect complètement différent car l'état de chaque instance de composant est unique.

Lorsque vous transmettez des propriétés à un composant, celles-ci sont appelées propriétés. Ne vous limitez pas aux attributs HTML, vous pouvez transmettre tout ce que vous voulez et y accéder via this.props à l'intérieur du composant. Cela nous permet de réutiliser le même composant mais de transmettre un ensemble différent de propriétés, telles que la « configuration » du composant.
Attributs

Sur la base de notre précédent exemple "Hello World!", nous avons l'attribut className sur le nœud HTML. À l'intérieur du composant, nous pouvons accéder à cette valeur en utilisant this.props.classname mais comme mentionné précédemment, vous pouvez transmettre ce que vous voulez. Pour notre liste déroulante, nous devons configurer la navigation en tant qu'objet, que le composant utilisera comme configuration à restituer. Commençons—

var navigationConfig = [];
 
var Navigation = React.createClass({
  render: function () {
    return (
      <div className="navigation">
         
      </div>
      );
  }
});
Copier après la connexion


React.render(, document.body);

如果现在能访问 this.props.config 的话,我们会受到一个空数组(navigationConfig 的值)。在我们进入到真正导航的编码前先让我们说明一下状态。

状态

如之前所讨论的,每一个组件都有其自己的”状态”。当要使用状态时,你要定义初始状态,让后才可以使用 this.setState 来更新状态。无论何时状态得到了更新,组件都会再一次调用 render 函数,拿新的值去替换或者改变之前渲染的值。这就是虚拟 DOM 的奥义 - 计算差异的算法实在 React 内部完成的,因此我们不用去以来 DOM 的更新了(因为 DOM 很慢)。React 会计算出差异并产生一堆指令的集合 (例如,加入向”navigation__link“加入”active“类,或者移除一个节点),并在 DOM 上执行它们。

使用导航,我们将下拉菜单打开保持在状态中。为此,添加一个 getInitialState 函数到类配置对象上,并返回带有我们想要的初始状态的对象。

var navigationConfig = [];
 
var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  render: function () {
    return (
      <div className="navigation">
         
      </div>
      );
  }
});
 
React.render(<Navigation config={ navigationConfig } />, document.body);
Copier après la connexion

你会发现我们将其设置成了-1。当我们准备去打开一个下拉菜单时,将使用状态里面的配置数组中的导航项的位置,而由于数组索引开始于0,我们就得使用 -1 来表示还没有指向一个导航项。

我们可以使用 this.state 来访问状态,因此如果我们去观察 atthis.state.openDropdown,应该会有 -1 被返回。

组件的生命周期

每个组件都有其“生命周期”—这是一系列你可以在组件配置里定义的函数,它们将在部件生命周期内被调用。我们已经看过了 getinitialstate 一它只被调用一次,在组件被挂载时调用。
componentWillMount

当组件要被挂载时这个函数被调用。这意味着我们可以在此运行组件功能必须的代码。为由于 render 在组件生命周期里被多次调用,我们一般会把只需要执行一次的代码放在这里,比如 XHR 请求。

var ExampleComponent = React.createClass({
  componentWillMount: function () {
    // xhr request here to get data
  },
  render: function () {
    // this gets called many times in a components life
    return (
      <div>
        Hello World!
      </div>
      );
  }
});
Copier après la connexion

componentDidMount

一旦你的组件已经运行了 render 函数,并实际将组件渲染到了 DOM 中,componentDidMount 就会被调用。我们可以在这儿做任何需要做的 DOM 操作,已经任何需要依赖于组件已经实际存在于 DOM 之后才能做的事情, 例如渲染一个图表。你可以通过调用 this.getDOMNode 在内部访问到 DOM 节点。

var ExampleComponent = React.createClass({
  componentDidMount: function () {
    var node = this.getDOMNode();
    // render a chart on the DOM node
  },
  render: function () {
    return (
      <div>
        Hello World!
      </div>
      );
  }
});
Copier après la connexion

componentWillUnmount

如果你准备吧组件从 DOM 移除时,这个函数将会被调用。这让我们可以在组件背后进行清理,比如移除任何我们已经绑定的事件监听器。如果我们没有在自身背后做清理,而当其中一个事件被触发时,就会尝试去计算一个没有载入的组件,React 就会抛出一个错误。

var ExampleComponent = React.createClass({
  componentWillUnmount: function () {
    // unbind any event listeners specific to this component
  },
  render: function () {
    return (
      <div>
        Hello World!
      </div>
      );
  }
});
Copier après la connexion

组件方法

React 也为组件提供了更方便我们工作的方法。它们会在组件的创建过程中被调用到。例如getInitialState,能让我们定义一个默认的状态,这样我们不用担心在代码里面对状态项目是否存在做进一步的检查了。
getDefaultProps

当我们创建组件时,可以按照我们的想法为组件的属性定义默认值。这意味着我们在调用组件时,如果给这些属性设置值,组件会有一个默认的“配置”,而我们就不用操心在下一行代码中检查属性这类事情了。

当你定义了组件时,这些默认的属性会被缓存起来,因而针对每个组件的实例它们都是一样的,并且不能被改变。对于导航组件,我们将配置指定为一个空的数组,因而就算没有传入配置,render 方法内也不会发生错误。

var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  render: function () {
    return (
      <div className="navigation">
         
      </div>
      );
  }
});
<p>React.render(<Navigation config={ navigationConfig } />, document.body);</p> 
Copier après la connexion

propTypes

我们也可以随意为每一个属性指定类型。这对于我们检查和处理属性的意外赋值非常有用。如下面的dropdown,我们指定只有数组才能放入配置。

var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  propTypes: {
    config: React.PropTypes.array
  },
  render: function () {
    return (
      <div className="navigation">
         
      </div>
      );
  }
});
 
React.render(<Navigation config={ navigationConfig } />, document.body);
Copier après la connexion

mixins

我们也可以在组件中加入 mixins。这是一个独立于 React 的基本组件(只是一个对象类型的配置)。这意味着,如果我们有两个功能类似的组件,就可以共享一个配置了(如果初始状态相同)。我们可以抽象化地在 mixin 中建立一个方法,这样就不用把相同的代码写上两次了。

var ExampleMixin = {
  componentDidMount: function () {
    // bind some event listeners here
  },
  componentWillUnmount: function () {
    // unbind those events here!
  }
};
 
var ExampleComponent = React.createClass({
  mixins: [ExampleMixin],
  render: function () {
    return (
      <div>
        Hello World!
      </div>
      );
  }
});
 
var AnotherComponent = React.createClass({
  mixins: [ExampleMixin],
  render: function () {
    return (
      <div>
        Hello World!
      </div>
      );
  }
});
Copier après la connexion

这样全部组件都有一样的 componentDidMount 和 componentWillUnmount 方法了,保存我们重写的代码。无论如何,你不能 override(覆盖)这些属性,如果这个属性是在mixin里设置的,它在这个组件中是不可覆盖的。

遍历循环

当我们有一个包含对象的数组,如何循环这个数组并渲染每一个对象到列表项中?JSX 允许你在任意 Javascript 文件中使用它,你可以映射这个数组并返回 JSX,然后使用 React 去渲染。

var navigationConfig = [
  {
    href: 'http://ryanclark.me',
    text: 'My Website'
  }
];
var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  propTypes: {
    config: React.PropTypes.array
  },
  render: function () {
    var config = this.props.config;
    var items = config.map(function (item) {
      return (
        <li className="navigation__item">
          <a className="navigation__link" href={ item.href }>
            { item.text }
          </a>
        </li>
        );
    });
    return (
      <div className="navigation">
        { items }
      </div>
      );
  }
});
React.render(<Navigation config={ navigationConfig } />, document.body);
Copier après la connexion

在 JSFilddle 中随意使用 navigationConfigin

导航配置由数组和对象组成,包括一个指向超链接的 href 属性和一个用于显示的 text 属性。当我们映射的时候,它会一个个依次通过这个数组去取得对象。我们可以访问 href 和 text,并在 HTML 中使用。当返回列表时,这个数组里的列表项都将被替换,所以我们把它放入 React 中处理时它将知道怎么去渲染了!

混编

到目前位置,我们已经做到了所有下拉列表的展开。我们需要知道被下来的项目是哪个,我们将使用 .children 属性去遍历我们的 navigationConfig 数组。接下来,我们可以通过循环来操作下拉的子元素条目。

var navigationConfig = [
  {
    href: 'http://ryanclark.me',
    text: 'My Website',
    children: [
      {
        href: 'http://ryanclark.me/how-angularjs-implements-dirty-checking/',
        text: 'Angular Dirty Checking'
      },
      {
        href: 'http://ryanclark.me/getting-started-with-react/',
        text: 'React'
      }
    ]
  }
];
var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  propTypes: {
    config: React.PropTypes.array
  },
  render: function () {
    var config = this.props.config;
    var items = config.map(function (item) {
      var children, dropdown;
      if (item.children) {
        children = item.children.map(function (child) {
          return (
            <li className="navigation__dropdown__item">
              <a className="navigation__dropdown__link" href={ child.href }>
                { child.text }
              </a>
            </li>
          );
        });
        dropdown = (
          <ul className="navigation__dropdown">
            { children }
          </ul>
        );
      }
      return (
        <li className="navigation__item">
          <a className="navigation__link" href={ item.href }>
            { item.text }
          </a>
          { dropdown }
        </li>
        );
    });
    return (
      <div className="navigation">
        { items }
      </div>
      );
  }
});
React.render(<Navigation config={ navigationConfig } />, document.body);

Copier après la connexion

实例在这里 - 但是我们还是能看见下来条目,尽管我们将 openDropdown 设置成为了 -1 。

我们可以通过在组件中访问 this.state ,来判断下拉是否被打开了,并且,我们可以为其添加一个新的 css 样式 class 来展现鼠标 hover 的效果。

var navigationConfig = [
  {
    href: 'http://ryanclark.me',
    text: 'My Website',
    children: [
      {
        href: 'http://ryanclark.me/how-angularjs-implements-dirty-checking/',
        text: 'Angular Dirty Checking'
      },
      {
        href: 'http://ryanclark.me/getting-started-with-react/',
        text: 'React'
      }
    ]
  }
];
var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  openDropdown: function (id) {
    this.setState({
      openDropdown: id
    });
  },
  closeDropdown: function () {
    this.setState({
      openDropdown: -1
    });
  },
  propTypes: {
    config: React.PropTypes.array
  },
  render: function () {
    var config = this.props.config;
    var items = config.map(function (item, index) {
      var children, dropdown;
      if (item.children) {
        children = item.children.map(function (child) {
          return (
            <li className="navigation__dropdown__item">
              <a className="navigation__dropdown__link" href={ child.href }>
                { child.text }
              </a>
            </li>
          );
        });
        var dropdownClass = 'navigation__dropdown';
        if (this.state.openDropdown === index) {
          dropdownClass += ' navigation__dropdown--open';
        }
        console.log(this.state.openDropdown, index);
        dropdown = (
          <ul className={ dropdownClass }>
            { children }
          </ul>
        );
      }
      return (
        <li className="navigation__item" onMouseOut={ this.closeDropdown } onMouseOver={ this.openDropdown.bind(this, index) }>
          <a className="navigation__link" href={ item.href }>
            { item.text }
          </a>
          { dropdown }
        </li>
        );
    }, this);
    return (
      <div className="navigation">
        { items }
      </div>
      );
  }
});
React.render(<Navigation config={ navigationConfig } />, document.body);
Copier après la connexion

在这里看实例 - 鼠标划过“My Website”,下拉即会展现。


在前面,我已经给每个列表项添加了鼠标事件。如你所见,我用的是 .bind (绑定) 调用,而非其它的方式调用 - 这是因为,当用户的鼠标划出元素区域,我们并不用关注光标在哪里,所有我们需要知晓的是,将下拉关闭掉,所以我们可以将它的值设置成为-1。但是,我们需要知晓的是当用户鼠标划入的时候哪个元素被下拉展开了,所以我们需要知道该参数(元素的索引)。 我们使用绑定的方式去调用而非简单的透过函数(function)去调用是因为我们需要通过 React 去调用。如果我们直接调用,那我们就需要一直调用,而不是在事件中调用他。

现在我们可以添加很多的条目到 navigationConfig 当中,而且我们也可以给他添加样式到下来功能当中。查看实例.

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!