Cet article parle principalement de l'utilisation de react.js, faire voir à tout le monde que réagir n'est pas aussi difficile qu'on le pense. Jetons maintenant un œil au contenu spécifique de cet article
1, React sont tous composants
React est conçu autour du concept de composants réutilisables. Vous définissez de petits composants et les combinez pour former des composants plus grands.
Peu importe leur taille, tous les composants sont réutilisables, même dans différents projets. La forme la plus simple du composant
React est simplement une fonction JavaScript ordinaire :
function Button (props) { // 这里返回一个 DOM元素,例如: return <buttontype="submit">{props.label}</button>; } // 将按钮组件呈现给浏览器 ReactDOM.render(<Buttonlabel="Save" />, mountNode)
Exemple 1 : Modifiez le code ci-dessus et appuyez sur Ctrl+Entrée pour exécuter (Note du traducteur : la traduction n'a pas cette fonction pour le moment, veuillez visiter le texte original pour l'utiliser fonction, la même ci-dessous)
Boutons entre parenthèses les balises seront expliquées plus tard. Ne vous inquiétez pas pour eux maintenant. ReactDOM sera également expliqué plus tard, mais si vous souhaitez tester cet exemple et tous les exemples suivants, la fonction de rendu ci-dessus est nécessaire. (Ce que React prendra le relais et contrôlera est le deuxième paramètre de ReactDOM.render, qui est l'élément DOM cible). Dans le jsComplete REPL, vous pouvez utiliser la variable spéciale mountNode.
Exemple 1 Notes sur :
La première lettre du nom du composant est en majuscule, Button. Ceci est nécessaire car nous aurons affaire à un mélange d’éléments HTML et d’éléments React. Les noms en minuscules sont réservés aux éléments HTML. En fait, nommez votre composant React « bouton » et vous constaterez que ReactDOM ignore cette fonction et la restitue simplement sous la forme d'un bouton HTML vide normal.
Chaque composant reçoit une liste de propriétés, tout comme l'élément HTML . Dans React, cette liste est appelée une propriété. Bien que vous puissiez nommer une fonction comme vous le souhaitez.
Dans la sortie de retour du composant de fonction Button ci-dessus, nous avons étrangement écrit un morceau de code qui ressemble à du HTML. Ce n’est en fait ni JavaScript ni HTML, et honnêtement, ce n’est même pas React.js. Pourtant, il est si populaire qu'il est devenu la valeur par défaut dans les applications React. C'est ce qu'on appelle JSX, qui est une extension JavaScript. JSX est aussi un compromis ! Allez-y et essayez de renvoyer d'autres éléments HTML dans la fonction ci-dessus pour voir comment ils sont pris en charge (par exemple, renvoyer un élément de saisie de texte).
2, Que produit JSX ?
Le exemple 1 ci-dessus peut être écrit en React.js pur sans JSX, comme suit :
function Button (props) { return React.createElement( "button", { type: "submit" }, props.label ); } // 要使用 Button,你可以这么做 ReactDOM.render( React.createElement(Button, { label:"Save" }), mountNode );
Exemple 2 : Écriture de composants React sans utiliser JSX
Dans l'API de premier niveau React , la fonction createElement est la fonction principale. Il s'agit de l'une des 7 API que vous devez apprendre. L'API de React est tellement petite.
Tout comme le DOM lui-même a une fonction document.createElement pour créer un élément spécifié par le nom de la balise, la fonction createElement de React est une fonction de haut niveau qui a les mêmes fonctionnalités que le document. createElement , mais il peut également être utilisé pour créer un élément qui représente un composant React. Nous utilisons ce dernier lorsque nous utilisons le composant Button dans l'exemple 2 ci-dessus.
Contrairement à document.createElement, createElement de React reçoit un paramètre dynamique après avoir reçu le deuxième paramètre, qui représente l'élément enfant de l'élément créé. Donc createElement crée en fait un arbre.
En voici un exemple :
const InputForm = React.createElement( "form", { target: "_blank", action:"https://google.com/search" }, React.createElement("p",null, "Enter input and click Search"), React.createElement("input", {className: "big-input" }), React.createElement(Button, { label:"Search" }) ); // InputForm 使用 Button组件,所以我们需要这样做: function Button (props) { return React.createElement( "button", { type: "submit" }, props.label ); } // 然后我们可以通过 .render方法直接使用 InputForm ReactDOM.render(InputForm, mountNode);
例 3:React创建元素的 API
上面例子中的一些事情值得注意:
InputForm 不是一个 React组件;它仅仅是一个 React 元素。这就是为什么我们可以在ReactDOM.render 中直接使用它并且可以在调用时不使用
React.createElement函数在前两个参数后接收了多个参数。从第3个参数开始的参数列表构成了创建元素的子项列表。
我们可以嵌套 React.createElement调用,因为它是 JavaScript。
当这个元素不需要属性时,React.createElement的第二个参数可以为空或者是一个空对象。
我们可以在 React 组件中混合HTML 元素。你可以将 HTML 元素作为内置的 React组件。
React 的 API试图和 DOM API 一样,这就是为什么我们在 input 元素中使用 className 代替 class 的原因。我们都希望如果 React 的 API 成为 DOM API 本身的一部分,因为,你知道,它要好得多。
上述的代码是当你引入 React 库的时候浏览器是怎样理解的。浏览器不会处理任何 JSX 业务。然而,我们更喜欢看到和使用 HTML,而不是那些 createElement 调用(想象一下只使用document.createElement 构建一个网站!)。这就是 JSX 存在的原因。取代上述调用 React.createElement 的方式,我们可以使用一个非常简单类似于HTML 的语法:
const InputForm = <form target="_blank"action="https://google.com/search"> <p>Enter input and clickSearch</p> <inputclassName="big-input" name="q" /> <Buttonlabel="Search" /> </form>; // InputForm “仍然”使用 Button 组件,所以我们也需要这样。 // JXS 或者普通的表单都会这样做 function Button (props) { // 这里返回一个 DOM元素。例如: return <buttontype="submit">{props.label}</button>; } // 然后我们可以直接通过 .render使用 InputForm ReactDOM.render(InputForm, mountNode);
例 4:为什么在 React中 JSX 受欢迎(和例3 相比)
注意上面的几件事:
这不是 HTML 代码。比如,我们仍然可以使用 className 代替 class。
我们仍在考虑怎样让上述的 JavaScript看起来像是 HTML。看一下我在最后是怎样添加的。
我们在上面(例 4)中写的就是 JSX。然而,我们要将编译后的版本(例 3)给浏览器。要做到这一点,我们需要使用一个预处理器将 JSX 版本转换为 React.createElement 版本。
这就是 JSX。这是一种折中的方案,允许我们用类似 HTML 的语法来编写我们的 React 组件,这是一个很好的方法。
“Flux” 在头部作为韵脚来使用,但它也是一个非常受欢迎的应用架构,由 Facebook推广。最出名的是 Redux,Flux 和 React 非常合适。
JSX,可以单独使用,不仅仅适用于 React。
3、 你可以在 JavaScript的任何地方使用 JSX
在 JSX 中,你可以在一对花括号内使用任何 JavaScript 表达式。
const RandomValue = () => <p> { Math.floor(Math.random() * 100)} </p>; // 使用: ReactDOM.render(<RandomValue />,mountNode);
例 5:在 JSX中使用 JavaScript 表达式
任何 JavaScript 表达式可以直接放在花括号中。这相当于在 JavaScript 中插入 ${} 模板。
这是 JSX 内唯一的约束:只有表达式。例如,你不能使用 if 语句,但三元表达式是可以的。
JavaScript 变量也是表达式,所以当组件接受属性列表时(不包括 RandomValue组件,props 是可选择的),你可以在花括号里使用这些属性。我们在上述(例 1)的 Button 组件是这样使用的。
JavaScript 对象也是表达式。有些时候我们在花括号中使用 JavaScript对象,这看起来像是使用了两个花括号,但是在花括号中确实只有一个对象。其中一个用例就是将 CSS 样式对象传递给响应中的特殊样式属性:
const ErrorDisplay = ({message}) => <p style={ { color: 'red',backgroundColor: 'yellow' } }> {message} </p>; // 使用 ReactDOM.render( <ErrorDisplay message="These aren't thedroids you're looking for" />, mountNode );
例 6:一个对象传递特殊的 React样式参数
注意我解构的只是在属性参数之外的信息。这只是 JavaScript。还要注意上面的样式属性是一个特殊的属性(同样,它不是 HTML,它更接近 DOM API)。我们使用一个对象作为样式属性的值并且这个对象定义样式就像我们使用 JavaScript 那样(我们可以这样做)。
你可以在 JSX 中使用 React 元素。因为这也是一个表达式(记住,一个 React 元素只是一个函数调用):
const MaybeError = ({errorMessage}) => <p> {errorMessage &&<ErrorDisplay message={errorMessage} />} </p>; // MaybeError 组件使用 ErrorDisplay组件 const ErrorDisplay = ({message}) => <p style={ { color: 'red',backgroundColor: 'yellow' } }> {message} </p>; // 现在我们使用 MaybeError组件: ReactDOM.render( <MaybeError errorMessage={Math.random() >0.5 ? 'Not good' : ''} />, mountNode );
例 7:一个 React元素是一个可以通过 {} 使用的表达式
上述 MaybeError 组件只会在有errorMessage 传入或者另外有一个空的 p 才会显示 ErrorDisplay 组件。React 认为 {true}、 {false}
{undefined} 和 {null} 是有效元素,不呈现任何内容。
我们也可以在 JSX 中使用所有的JavaScript 的集合方法(map、reduce 、filter、 concat 等)。因为他们返回的也是表达式:
const Doubler = ({value=[1, 2, 3]}) => <p> {value.map(e => e * 2)} </p>; // 使用下面内容 ReactDOM.render(<Doubler />, mountNode);
例 8:在 {}中使用数组
请注意我是如何给出上述 value 属性的默认值的,因为这全部都只是 JavaScript。注意我只是在 p 中输出一个数组表达式。React 是完全可以的。它只会在文本节点中放置每一个加倍的值。
4、 你可以使用 JavaScript类写 React 组件
简单的函数组件非常适合简单的需求,但是有的时候我们需要的更多。React也支持通过使用 JavaScript 类来创建组件。这里 Button 组件(在例 1 中)就是使用类的语法编写的。
class Button extends React.Component { render() { return<button>{this.props.label}</button>; } } // 使用(相同的语法) ReactDOM.render(<Buttonlabel="Save" />, mountNode);
例 9:使用 JavaScript类创建组件
类的语法是非常简单的:定义一个扩展的 React.Component类(另一个你需要学习的 React 的顶级 API)。该类定义了一个单一的实例函数 —— render(),并使函数返回虚拟 DOM 对象。每一次我们使用基于类的 Button 组件(例如,通过 ),React 将从这个基于类的组件中实例化对象,并在 DOM 树中使用该对象。
这就是为什么上面的例子中我们可以在 JSX中使用 this.props.label 渲染输出的原因,因为每一个组件都有一个特殊的称为props 的 实例 属性,这让所有的值传递给该组件时被实例化。
由于我们有一个与组件的单个使用相关联的实例,所以我们可以按照自己的意愿定制该实例。例如,我们可以通过使用常规 JavaScript构造函数来构造它:
class Button extends React.Component { constructor(props) { super(props); this.id = Date.now(); } render() { return <buttonid={this.id}>{this.props.label}</button>; } } // 使用 ReactDOM.render(<Buttonlabel="Save" />, mountNode);
例 10:自定义组件实例
我们也可以定义类的原型并且在任何我们希望的地方使用,包括在返回的 JSX输出的内部:
class Button extends React.Component { clickCounter = 0; handleClick = () => { console.log(`Clicked: ${++this.clickCounter}`); } render() { return ( <button id={this.id}onClick={this.handleClick}> {this.props.label} </button> ); } } // 使用 ReactDOM.render(<Buttonlabel="Save" />, mountNode);
例 11:使用类的属性(通过单击保存按钮进行测试)
注意上述例 11 中的几件事情
handleClick 函数使用 JavaScript 新提出的 class-field syntax 语法。这仍然是 stage-2,但是这是访问组件安装实例(感谢箭头函数)最好的选择(因为很多原因)。然而,你需要使用类似 Babel 的编译器解码为 stage-2(或者仅仅是类字段语法)来让上述代码工作。 jsComplete REPL 有预编译功能。
// 错误:
onClick={this.handleClick()}
// 正确:
onClick={this.handleClick}
5、React中的事件:两个重要的区别
当处理 React 元素中的事件时,我们与 DOM API 的处理方式有两个非常重要的区别:
所有 React 元素属性(包括事件)都使用 camelCase 命名,而不是 lowercase。例如是 onClick 而不是 onclick。
我们将实际的 JavaScript 函数引用传递给事件处理程序,而不是字符串。例如是 onClick={handleClick} 而不是onClick="handleClick"。
React 用自己的对象包装 DOM对象事件以优化事件处理的性能,但是在事件处理程序内部,我们仍然可以访问 DOM对象上所有可以访问的方法。React 将经过包装的事件对象传递给每个调用函数。例如,为了防止表单提交默认提交操作,你可以这样做:
class Form extends React.Component { handleSubmit = (event) => { event.preventDefault(); console.log('Form submitted'); }; render() { return ( <formonSubmit={this.handleSubmit}> <buttontype="submit">Submit</button> </form> ); } } // 使用 ReactDOM.render(<Form />, mountNode);
例 12:使用包装过的对象
6、每一个 React组件都有一个故事:第 1 部分
以下仅适用于类组件(扩展 React.Component)。函数组件有一个稍微不同的故事。
首先,我们定义了一个模板来创建组件中的元素。
然后,我们在某处使用 React。例如,在 render 内部调用其他的组件,或者直接使用 ReactDOM.render。
然后,React 实例化一个对象然后给它设置 props 然后我们可以通过 this.props 访问。这些属性都是我们在第 2 步传入的。
因为这些全部都是 JavaScript,constructor方法将会被调用(如果定义的话)。这是我们称之为的第一个:组件生命周期方法。
接下来 React 计算渲染之后的输出方法(虚拟 DOM 节点)。
因为这是 React 第一次渲染元素,React将会与浏览器连通(代表我们使用 DOM API)来显示元素。这整个过程称为 mounting。
接下来 React 调用另一个生命周期函数,称为 componentDidMount。我们可以这样使用这个方法,例如:在 DOM 上做一些我们现在知道的在浏览器中存在的东西。在此生命周期方法之前,我们使用的 DOM 都是虚拟的。
一些组件的故事到此结束,其他组件得到卸载浏览器 DOM中的各种原因。在后一种情况发生时,会调用另一个生命周期的方法,componentWillUnmount。
任何 mounted 的元素的状态都可能会改变。该元素的父级可能会重新渲染。无论哪种情况,mounted 的元素都可能接收到不同的属性集。React 的魔力就是这儿,我们实际上需要的正是 React 的这一点!在这一点之前,说实话,我们并不需要 React。
组价的故事还在继续,但是在此之前,我们需要理解我所说的这种状态。
7、React组件可以具有私有状态
以下只适用于类组件。我有没有提到有人叫表象而已的部件 dumb?
状态类是任何 React 类组件中的一个特殊字段。React 检测每一个组件状态的变化,但是为了 React 更加有效,我们必须通过 React 的另一个 API 改变状态字段,这就是我们要学习的另一个 API —— this.setState:
class CounterButton extends React.Component { state = { clickCounter: 0, currentTimestamp: new Date(), }; handleClick = () => { this.setState((prevState) => { return { clickCounter:prevState.clickCounter + 1 }; }); }; componentDidMount() { setInterval(() => { this.setState({currentTimestamp: new Date() }) }, 1000); } render() { return ( <p> <buttononClick={this.handleClick}>Click</button> <p>Clicked:{this.state.clickCounter}</p> <p>Time:{this.state.currentTimestamp.toLocaleString()}</p> </p> ); } } // 使用 ReactDOM.render(<CounterButton />,mountNode);
例 13:setState的 API
这可能是最重要的一个例子因为这将是你完全理解 React基础知识的方式。这个例子之后,还有一些小事情需要学习,但从那时起主要是你和你的 JavaScript 技能。
让我们来看一下例 13,从类开始,总共有两个,一个是一个初始化的有初始值为 0 的 clickCounter 对象和一个从 new Date() 开始的 currentTimestamp。
另一个类是 handleClick 函数,在渲染方法中我们给按钮元素传入 onClick 事件。通过使用 setState 的 handleClick 方法修改了组件的实例状态。要注意到这一点。
另一个我们修改状态的地方是在一个内部的定时器,开始在内部的componentDidMount生命周期方法。它每秒钟调用一次并且执行另一个函数调用this.setState。
在渲染方法中,我们使用具有正常读语法的状态上的两个属性(没有专门的 API)。
现在,注意我们更新状态使用两种不同的方式:
通过传入一个函数然后返回一个对象。我们在 handleClick函数内部这样做。
通过传入一个正则对象,我们在在区间回调中这样做。
这两种方式都是可以接受的,但是当你同时读写状态时,第一种方法是首选的(我们这样做)。在区间回调中,我们只向状态写入而不读它。当有问题时,总是使用第一个函数作为参数语法。伴随着竞争条件这更安全,因为 setstate实际上是一个异步方法。
Comment devons-nous mettre à jour le statut ? Nous renvoyons un objet avec la valeur que nous souhaitons mettre à jour. Notez que lors de l'appel de setState, nous transmettons soit une propriété de l'état, soit aucune. C'est tout à fait bien car setState fusionne en fait l'argument de fonction que vous lui avez transmis (la valeur de retour) avec l'état existant, donc ne pas spécifier de propriété lors de l'appel de setState signifie que nous ne voulons pas modifier la propriété (mais pas la supprimer).
8, React réagira
Le nom de React vient de l'État Dérivé de la réaction du changement (bien qu'il n'y ait pas de réaction, elle est aussi dans un calendrier). Il y a une blague ici, React devrait s'appeler Schedule !
Cependant, lorsque l'état d'un composant est mis à jour, ce que nous observons à l'œil nu est une réaction à cette mise à jour et reflète automatiquement la mise à jour dans le DOM du navigateur (si nécessaire).
Considérez l'entrée de la fonction de rendu comme deux types :
Attributs transmis via l'élément parent
Et un état privé interne qui peut être mis à jour à tout moment
Lorsque l'entrée de la fonction de rendu change, la sortie peut également changer.
React enregistre un historique des rendus, et lorsqu'il voit un rendu différent du précédent, il calcule la différence entre eux et l'ajoute. dans les opérations DOM réelles effectuées dans le DOM.
9, React est votre code
Vous pouvez considérer React comme le proxy nous utilisons pour communiquer avec le navigateur. Prenons l'exemple de l'affichage de l'horodatage actuel ci-dessus. Au lieu de devoir accéder manuellement au navigateur et appeler les opérations de l'API DOM toutes les secondes pour rechercher et mettre à jour l'élément p#timestamp, nous modifions simplement l'attribut state du composant et React fait le travail en notre nom pour communiquer avec le navigateur. Je pense que c'est la vraie raison pour laquelle React est si populaire ; nous n'aimons tout simplement pas parler à M. Browser (et aux nombreux dialectes du langage DOM qu'il parle), et React nous est transmis volontairement, gratuitement !
10, Chaque composant React a une histoire : Partie 2
Maintenant, nous savons quand l'état d'un composant change, jetons un coup d'œil aux derniers concepts sur ce processus.
Un composant peut avoir besoin d'un nouveau rendu lorsque son état est mis à jour ou lorsque son processus parent décide de modifier les propriétés qu'il a transmises au composant.
Si ce dernier cas se produit, React appellera une autre méthode de cycle de vie : composantWillReceiveProps.
Si l'objet d'état ou les propriétés transmises changent, React a une décision importante à prendre : le composant doit-il être mis à jour dans le DOM ? C'est pourquoi il appelle une autre méthode importante du cycle de vie, ShouldComponentUpdate. Cette méthode est pratique, donc si vous devez personnaliser ou optimiser vous-même le processus de rendu, vous devez répondre à cette question en renvoyant vrai ou faux.
Sans ShouldComponentUpdate personnalisé, les événements par défaut de React se gèrent bien dans la plupart des cas.
Tout d'abord, une autre méthode de cycle de vie sera appelée à ce moment-là : composantWillUpdate. React calculera ensuite la sortie nouvellement rendue et la comparera à la dernière sortie rendue.
Si le résultat rendu est le même qu'avant, React ne fait rien pour le traiter (pas besoin de parler à M. Browser).
S'il y a une différence, React communique la différence au navigateur, comme nous l'avons vu précédemment.
Dans tous les cas, une fois qu'une mise à jour se produit, peu importe comment (même avec le même résultat), React appellera la méthode de cycle de vie finale : composantDidUpdate.
Les méthodes de cycle de vie sont des issues de secours. Si vous ne faites rien de spécial, vous pouvez créer une application complète sans eux. Ils sont très pratiques pour analyser ce qui se passe dans l'application et optimiser davantage les performances de ReactUpdate
Cet article se termine ici (si vous voulez en voir plus, rendez-vous sur le site PHP chinois Apprenez-en dans la colonne Manuel de l'utilisateur React ). Si vous avez des questions, vous pouvez laisser un message ci-dessous.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!