在深入了解 React 之前了解有关 JavaScript 和 Web 开发的所有信息。不幸的是, 我们生活在一个不完美的世界里, 所以在 React 之前对所有 JavaScript 进行大做笑只会让你流血。如果您已经拥有了一些 JavaScript 的经验,那么在 React 之前,您需要学习的只是用于开发 React 应用程序的 JavaScript 功能。关于JavaScript,在学习React之前,你应该对它感到自在:

这是20%的JavaScript功能,你将使用80%的时间,所以在本教程中,我将帮助您学习他们所有。

探索创建React应用程序

开始学习 React 的通常情况是运行包,它设置运行 React 所需的一切。然后,在过程完成后,打开将呈现我们整个应用程序中唯一的 React 类:create-react-app``````src/app.js

import React, { Component } from ‘react’; import logo from ‘./logo.svg’; import ‘./App.css’;

class App extends Component { render() { return (

logo

Edit src/App.js and save to reload.

Learn React
); } }

export default App;

如果您以前从未学习过 ES6,你会认为此类语句是 React 的一个功能。它实际上是 ES6 的新功能,这就是为什么正确学习 ES6 使您能够更好地了解 React 代码的原因。我们将从 ES6 课程开始。

ES6 类

ES6 引入了类语法,其使用方式与 OO 语言(如 Java 或 Python)类似。ES6 中的基本类将看起来像:

class Developer { constructor(name){ this.name = name; }

hello(){ return ‘Hello World! I am ’ + this.name + ’ and I am a web developer’; } }

class语法后跟一个标识符(或简单名称),可用于创建新对象。该方法始终在对象初始化中调用。传递到对象的任何参数都将传递到新对象中。例如:constructor

var nathan = new Developer(‘Nathan’); nathan.hello(); // Hello World! I am Nathan and I am a web developer

类可以定义尽可能多的方法,因为需要,在这种情况下,我们有返回字符串的方法。hello

类继承

类可以定义另一个类,从该类初始化的新对象将具有这两个类的所有方法。extends

class ReactDeveloper extends Developer { installReact(){ return ‘installing React .. Done.’; } }

var nathan = new ReactDeveloper(‘Nathan’); nathan.hello(); // Hello World! I am Nathan and I am a web developer nathan.installReact(); // installing React .. Done.

另一个类通常称为_子类或__子类的_类,而正在扩展的类称为_父类或__超级类_。子类还可以_重写_父类中定义的方法,这意味着它将用定义的新方法替换方法定义。例如,让我们重写函数:extends``````hello

class ReactDeveloper extends Developer { installReact(){ return ‘installing React .. Done.’; }

hello(){ return ‘Hello World! I am ’ + this.name + ’ and I am a REACT developer’; } }

var nathan = new ReactDeveloper(‘Nathan’); nathan.hello(); // Hello World! I am Nathan and I am a REACT developer

给你。类中的方法已被覆盖。hello``````Developer

在React中使用

现在,我们了解 ES6 类和继承,我们可以理解 在 中定义的 React 类。这是一个 React 组件,但实际上只是一个正常的 ES6 类,它继承了从 React 包导入的 React 组件类的定义。src/app.js

import React, { Component } from ‘react’;

class App extends Component { // class content render(){ return (

Hello React!

) } }

这使我们能够使用方法,JSX,其他方法。所有这些定义都在类中。但是,正如我们稍后将看到的,类并不是定义 React 组件的唯一方法。如果不需要状态和其他生命周期方法,可以改为使用函数。render()``````this.state``````Component

使用 ES6 和let``````const

由于 JavaScript 关键字全局声明变量,因此在 ES6 中引入了两个新的变量声明来解决此问题,即 和 。它们都是一样的,它们用于声明变量。区别在于不能在声明后更改其值,而可以。这两个声明都是本地的,这意味着如果在函数范围内声明,则不能在函数之外调用它。var``````let``````const``````const``````let``````let

const name = “David”; let age = 28; var occupation = “Software Engineer”;

使用哪一个?

经验法则是默认使用声明变量。稍后,当您撰写应用程序时,您将意识到需要更改的价值。这是您应该重构为 的时间。希望它能让你习惯新的关键字,并且你会开始识别应用程序中需要使用或 的模式。const``````const``````const``````let``````const``````let

我们什么时候在React中使用它?

每次我们需要变量。请考虑以下示例:

import React, { Component } from ‘react’;

class App extends Component { // class content render(){ const greeting = ‘Welcome to React’; return (

{greeting}

) } }

由于问候语在整个应用程序生命周期中不会改变,因此我们使用此处定义它。const

箭头功能

Arrow 函数是一种新的 ES6 功能,在现代代码库中几乎被广泛使用,因为它使代码保持简洁和可读性。此功能允许我们使用较短的语法编写函数

// regular function const testFunction = function() { // content.. }

// arrow function const testFunction = () => { // content.. }

如果您是经验丰富的 JS 开发人员,则从常规函数语法移动到箭头语法可能首先会让人不舒服。当我学习箭头函数时,我使用这个简单的 2 个步骤来重写我的函数:

  1. 删除函数关键字
  2. 添加脂肪箭头符号后=>``````()

括号仍用于传递参数,如果只有一个参数,可以省略括号。

const testFunction = (firstName, lastName) => { return firstName+’ ‘+lastName; }

const singleParam = firstName => { return firstName; }

隐式返回

如果您的箭头函数只有一行,则无需使用关键字和大括号即可返回值return``````{}

const testFunction = () => ‘hello there.’; testFunction();

在React中使用

创建 React 组件的另一种方法是使用箭头函数。React采取箭头功能:

const HelloWorld = (props) => { return

{props.hello}

; }

相当于 ES6 类组件

class HelloWorld extends Component { render() { return (

{props.hello}

; ); } }

在 React 应用程序中使用箭头函数会使代码更加简洁。但它也会从组件中删除状态的使用。这种类型的组件称为无_状态功能组件_。您可以在许多 React 教程中找到该名称。

数组和对象的析构分配

ES6 中引入的最有用的新语法之一,解构赋值只是复制对象或数组的一部分,并将它们放入命名变量中。一个快速示例:

const developer = { firstName: ‘Nathan’, lastName: ‘Sebhastian’, developer: true, age: 25, }

//destructure developer object const { firstName, lastName } = developer; console.log(firstName); // returns ‘Nathan’ console.log(lastName); // returns ‘Sebhastian’ console.log(developer); // returns the object

如您所看到的,我们将名字和姓氏从对象分配到新的变量 和 中。现在,如果要放入名为 ? 的新变量,怎么办?developer``````firstName``````lastName``````firstName``````name

const { firstName:name } = developer; console.log(name); // returns ‘Nathan’

解构也适用于数组,只有它使用索引而不是对象键:

const numbers = [1,2,3,4,5]; const [one, two] = numbers; // one = 1, two = 2

您可以通过 使用 传递来从析构中跳过某些索引:,

const [one, two, , four] = numbers; // one = 1, two = 2, four = 4

在React中使用

主要用于方法的析构,例如:state

reactFunction = () => { const { name, email } = this.state; };

或在功能无状态组件中,请考虑上一章中的示例:

const HelloWorld = (props) => { return

{props.hello}

; }

我们可以立即销毁参数:

const HelloWorld = ({ hello }) => { return

{hello}

; }

解构数组也用于 React 的挂钩:useState

const [user, setUser] = useState(’’);

地图和过滤器

尽管本教程重点介绍 ES6,但需要提及 JavaScript 数组和方法,因为它们可能是构建 React 应用程序时使用最多的 ES5 功能之一。特别是在处理数据方面。map``````filter

这两种方法在处理数据时使用得多。例如,假设从 API 结果提取返回 JSON 数据数组:

const users = [ { name: ‘Nathan’, age: 25 }, { name: ‘Jack’, age: 30 }, { name: ‘Joe’, age: 28 }, ];

然后,我们可以在 React 中呈现项目列表,如下所示:

import React, { Component } from ‘react’;

class App extends Component { // class content render(){ const users = [ { name: ‘Nathan’, age: 25 }, { name: ‘Jack’, age: 30 }, { name: ‘Joe’, age: 28 }, ];

return (
  <ul>
    {users
      .map(user => <li>{user.name}</li>)
    }
  </ul>
)

} }

我们还可以筛选渲染中的数据。

    {users .filter(user => user.age > 26) .map(user =>
  • {user.name}
  • ) }

ES6 模块系统

ES6 模块系统使 JavaScript 能够导入和导出文件。让我们再次查看代码,以便对此进行解释。src/app.js

import React, { Component } from ‘react’; import logo from ‘./logo.svg’; import ‘./App.css’;

class App extends Component { render() { return (

logo

Edit src/App.js and save to reload.

Learn React
); } }

export default App;

在第一行代码中,我们看到导入语句:

import React, { Component } from ‘react’;

最后一行我们看到语句:export default

export default App;

为了理解这些语句,我们先讨论一下模块语法。

模块只是使用 关键字导出一个或多个值(可以是对象、函数或变量)的 JavaScript 文件。首先,创建一个在目录中命名的新文件export``````util.js``````src

touch util.js

然后在它里面写一个函数。这是默认导出

export default function times(x) { return x * x; }

或多个命名导出

export function times(x) { return x * x; }

export function plusTwo(number) { return number + 2; }

然后,我们可以导入它src/App.js

import { times, plusTwo } from ‘./util.js’;

console.log(times(2)); console.log(plusTwo(3));

每个模块可以有多个命名导出,但只能有一个默认导出。无需使用大括号和相应的导出函数名称即可导入默认导出:

// in util.js export default function times(x) { return x * x; }

// in app.js import k from ‘./util.js’;

console.log(k(4)); // returns 16

但对于命名导出,必须使用大括号和确切名称进行导入。或者,导入可以使用别名来避免对两个不同的导入具有相同的名称:

// in util.js export function times(x) { return x * x; }

export function plusTwo(number) { return number + 2; }

// in app.js import { times as multiplication, plusTwo as plus2 } from ‘./util.js’;

从绝对名称导入,如:

import React from ‘react’;

将使 JavaScript 检查相应的包名称。因此,如果要导入本地文件,不要忘记使用正确的路径。node_modules

在React中使用

显然,我们在文件中看到了这一点,然后在呈现导出组件的文件中看到了这一点。现在让我们忽略服务工部分。src/App.js``````index.js``````App

//index.js file

import React from ‘react’; import ReactDOM from ‘react-dom’; import ‘./index.css’; import App from ‘./App’; import * as serviceWorker from ‘./serviceWorker’;

ReactDOM.render(, document.getElementById(‘root’));

// If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: http://bit.ly/CRA-PWA serviceWorker.unregister();

请注意如何从目录导入应用,并且已省略扩展名。只有在导入 JavaScript 文件时,我们才能删除文件扩展名,但我们必须将它包括在其他文件(如 ) 中。我们还导入另一个节点模块 ,这使我们能够将 React 组件呈现到 HTML 元素中。./App``````.js``````.css``````react-dom

对于 PWA,它是使 React 应用程序脱机工作的功能,但由于默认情况下禁用它,因此无需在开始时学习它。在您有足够的信心构建 React 用户界面后,最好学习 PWA。

结论

React 的厉害之处是,它不会像其他 Web 框架一样在 JavaScript 的上面添加任何外国抽象层。这就是为什么 React 在 JS 开发人员中变得非常流行。它只是使用最好的JavaScript,使构建用户界面更容易和可维护。React 应用程序中的 JavaScript 确实比 React specfix 语法更多,因此,一旦您更好地了解 JavaScript(尤其是 ES6),就可以自信地编写 React 应用程序。但这并不意味着您必须掌握有关 JavaScript 的一切才能开始编写 React 应用程序。现在就去写一个,随着机会的来,你将成为一个更好的开发人员。