在你学习React之前必备的JavaScript基础

开发 前端
这篇文章告诉你最基本要掌握的知识,让你快速的写起来。但是后期的提高,仍旧需要去夯实 Javascript 的基础。

 [[267257]]

写在前面

为了不浪费大家的宝贵时间,在开头申明一下,这篇文章针对的阅读对象是:没有写过 React 或者刚刚才接触 React 并且对于 ES6 的语法不太了解的同学,这是一篇基础入门的文章,在一开始我并没有准备翻译一篇这样的基础文章,但是在阅读完全文之后,我想起自己刚开始学习 React 时的迷茫,ES6 有那么多,我需要掌握多少呢?对于一个急于上手 React 写代码的人来说,这篇文章告诉你最基本要掌握的知识,让你快速的写起来。但是后期的提高,仍旧需要去夯实 Javascript 的基础。

前言

在理想的状态下,你可以在深入了解React之前了解 JavaScript 和Web 开发的所有知识。 不幸的是,我们生活在一个不***的世界,所以在 React 之前把所有的JavaScript 都咀嚼一遍只会让你举步维艰。 如果你已经拥有一些 JavaScript 经验,那么在 React 之前你需要学习的只是实际用于开发 React 应用程序的 JavaScript 功能。 在学习 React之前你应该学会的JavaScript 的知识点:

  •  ES6 类
  •  使用 let / const 声明变量
  •  箭头函数
  •  解构赋值
  •  Map 和 filter
  •  ES6 模块系统

这是你将在 80% 的时间内使用的20% 的 JavaScript 新特性,因此在本文中,我将帮助你学习所有这些特性。

创建 React 应用程序的探索

开始学习 React 的常见情况是运行 create-react-app 包,它会设置运行 React 所需的一切。 该过程完成之后,打开 src / app.js 这里给我们展示了整个应用程序中唯一的 React 类: 

  1. import React, { Component } from 'react';  
  2. import logo from './logo.svg';  
  3. import './App.css';  
  4. class App extends Component {  
  5.   render() {  
  6.     return (  
  7.       <div className="App">  
  8.         <header className="App-header">  
  9.           <img src={logo} className="App-logo" alt="logo" />  
  10.           <p>  
  11.             Edit <code>src/App.js</code> and save to reload.  
  12.           </p>  
  13.           <a  
  14.             className="App-link"  
  15.             href="https://reactjs.org"  
  16.             target="_blank"  
  17.             rel="noopener noreferrer"  
  18.           >  
  19.             Learn React  
  20.           </a>  
  21.         </header>  
  22.       </div>  
  23.     );  
  24.   }  
  25.  
  26. export default App; 

如果之前你从未学习过 ES6 ,那么你可能认为这个 class 语句是 React 的一个特性。 实际上这是 ES6 的一个新特性,这就是为什么正确学习 ES6 可以让你更好地理解 React 代码。 我们将从 ES6 的类开始。

ES6 的类

ES6 引入了 class 语法,类似于 Java 或 Python 等 OO(面向对象) 语言。 ES6 中的基本类如下所示: 

  1. class Developer {  
  2.   constructor(name){  
  3.     this.name = name;  
  4.   }  
  5.   hello(){  
  6.     return 'Hello World! I am ' + this.name + ' and I am a web developer';  
  7.   }  

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

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

类可以定义任意它所需的方法,在这种情况下,我们定义了一个返回字符串的 hello 方法。

类继承

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

  1. class ReactDeveloper extends Developer {  
  2.   installReact(){  
  3.     return 'installing React .. Done.';  
  4.   }  
  5.  
  6. var nathan = new ReactDeveloper('Nathan');  
  7. nathan.hello(); // Hello World! I am Nathan and I am a web developer  
  8. nathan.installReact(); // installing React .. Done. 

继承另一个类的类,通常称为 child 类或 sub 类,而正在扩展的类称为 parent 类或 super 类。 子类也可以覆盖父类中定义的方法,这意味着它将使用自己定义的新方法来替换父类方法的定义。 例如,让我们覆盖 hello 函数: 

  1. class ReactDeveloper extends Developer {  
  2.   installReact(){  
  3.     return 'installing React .. Done.';  
  4.   } 
  5.   hello(){  
  6.     return 'Hello World! I am ' + this.name + ' and I am a REACT developer';  
  7.   }  
  8.  
  9. var nathan = new ReactDeveloper('Nathan');  
  10. nathan.hello(); // Hello World! I am Nathan and I am a REACT developer 

就这样,我们重写了 Developer 类中的 hello 方法。

在React 中使用

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

  1. import React, { Component } from 'react';  
  2. class App extends Component {  
  3.   // class content  
  4.   render(){  
  5.     return (  
  6.       <h1>Hello React!</h1>  
  7.     )  
  8.   }  

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

使用 ES6 中的 let 和 const 来声明变量

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

  1. const name = "David" 
  2. let age = 28 
  3. var occupation = "Software Engineer"

用哪个呢?

按以往经验来说,默认使用 const 声明变量。 稍后当您编写应用程序时,当你意识到 const 的值需要更改,才是你应该将const 重构为 let 时。 希望它会让你习惯新的关键字,并且你将开始认识到应用程序中需要使用 const 或 let 的模式。

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

在我们需要变量的时候: 

  1. import React, { Component } from 'react';  
  2. class App extends Component {  
  3.   // class content  
  4.   render(){  
  5.     const greeting = 'Welcome to React' 
  6.     return (  
  7.       <h1>{greeting}</h1>  
  8.     )  
  9.   }  

在整个应用的生命周期中 greeting 并不会发生改变,所以我们在这里使用 const

箭头函数

箭头函数是 ES6 的一种新特性,在现代代码库中几乎被广泛使用,因为它使代码简洁易读。 它允许我们使用更短的语法编写函数。 

  1. // regular function  
  2. const testFunction = function() {  
  3.   // content..  
  4.  
  5. // arrow function  
  6. const testFunction = () => {  
  7.   // content..  

如果您是一位经验丰富的 JS 开发人员,那么从常规函数语法转换为箭头语法可能会让您感到不舒服。 当我学习箭头函数时,我用这两个简单的步骤来重写我的函数:

  1.  移除 function 关键字
  2.  在 () 后面加上 =>

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

  1. const testFunction = (firstName, lastName) => {  
  2.   return firstName+' '+lastName;  
  3.  
  4. const singleParam = firstName => {  
  5.   return firstName;  

隐藏的 return

如果箭头函数只有一行,则可以返回值而无需使用 return 关键字以及大括号。 

  1. const testFunction = () => 'hello there.';  
  2. testFunction();  

在 React 中的使用 

  1. const HelloWorld = (props) => {  
  2.   return <h1>{props.hello}</h1> 

等同于 ES6 的类组件 

  1. class HelloWorld extends Component {  
  2.   render() {  
  3.     return (  
  4.       <h1>{props.hello}</h1> 
  5.     );  
  6.   }  

在 React 应用程序中使用箭头功能可使代码更简洁。 但它也会从组件中删除状态的使用。 这种类型的组件称为无状态功能组件。 你会在许多 React 教程中看到这个名字。

解析数组和对象的赋值

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

  1. const developer = {  
  2.   firstName: 'Nathan',  
  3.   lastName: 'Sebhastian',  
  4.   developer: true,  
  5.   age: 25,  
  6.  
  7. //destructure developer object  
  8. const { firstName, lastName } = developer;  
  9. console.log(firstName); // returns 'Nathan'  
  10. console.log(lastName); // returns 'Sebhastian'  
  11. console.log(developer); // returns the object 

如您所见,我们将开发人员对象中的 firstName 和 lastName 分配给新变量 firstName 和 lastName 。 现在,如果要将 firstName 放入名为 name 的新变量中,该怎么办? 

  1. const { firstName:name } = developer;  
  2. console.log(name); // returns 'Nathan' 

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

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

你可以通过传入 , 来在解构的过程中跳过一些下标: 

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

在 React 中的使用

最常见是在方法中解构 state: 

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

或者是在无状态的函数组件中,结合之前提到的例子: 

  1. const HelloWorld = (props) => {  
  2.   return <h1>{props.hello}</h1> 

我们可以立即简单地解构参数: 

  1. const HelloWorld = ({ hello }) => {  
  2.   return <h1>{hello}</h1> 

Map 和 filter

虽然本文侧重于 ES6 ,但需要提及 JavaScript 数组 Map 和 filter 方法,因为它们可能是构建 React 应用程序时最常用的 ES5 功能之一。 特别是在处理数据上。

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

  1. const users = [  
  2.   { name: 'Nathan', age: 25 },  
  3.   { name: 'Jack', age: 30 },  
  4.   { name: 'Joe', age: 28 },  
  5. ]; 

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

  1. import React, { Component } from 'react';  
  2. class App extends Component {  
  3.   // class content  
  4.   render(){  
  5.     const users = [  
  6.       { name: 'Nathan', age: 25 },  
  7.       { name: 'Jack', age: 30 },  
  8.       { name: 'Joe', age: 28 },  
  9.     ];  
  10.     return (  
  11.       <ul>  
  12.         {users  
  13.           .map(user => <li>{user.name}</li> 
  14.         }  
  15.       </ul>  
  16.     )  
  17.   }  

我们同样可以在 render 中筛选数据 

  1. <ul>  
  2.   {users  
  3.     .filter(user => user.age > 26)  
  4.     .map(user => <li>{user.name}</li> 
  5.   }  
  6. </ul> 

ES6 模块系统

ES6 模块系统使 JavaScript 能够导入和导出文件。 让我们再看一下 src / app.js 代码来解释这一点。 

  1. import React, { Component } from 'react';  
  2. import logo from './logo.svg';  
  3. import './App.css';  
  4. class App extends Component {  
  5.   render() {  
  6.     return (  
  7.       <div className="App">  
  8.         <header className="App-header">  
  9.           <img src={logo} className="App-logo" alt="logo" />  
  10.           <p>  
  11.             Edit <code>src/App.js</code> and save to reload.  
  12.           </p>  
  13.           <a  
  14.             className="App-link"  
  15.             href="https://reactjs.org"  
  16.             target="_blank"  
  17.             rel="noopener noreferrer"  
  18.           >  
  19.             Learn React  
  20.           </a>  
  21.         </header>  
  22.       </div>  
  23.     );  
  24.   }  
  25.  
  26. export default App; 

在***行代码中我们看到 import 语句: 

  1. import React, { Component } from 'react'; 

在***行代码中我们看到 export default 语句: 

  1. export default App; 

要理解这些语句,我们先讨论模块语法。

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

  1. touch util.js 

然后我们在这里面写一个函数,使用一个默认导出 

  1. export default function times(x) {  
  2.   return x * x;  

或多个命名的导出 

  1. export function times(x) {  
  2.   return x * x;  
  3.  
  4. export function plusTwo(number) {  
  5.   return number + 2;  

然后我们可以在 src/App.js 中引入它。 

  1. import { times, plusTwo } from './util.js';  
  2. console.log(times(2));  
  3. console.log(plusTwo(3)); 

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

  1. // in util.js  
  2. export default function times(x) {  
  3.   return x * x;  
  4.  
  5. // in app.js  
  6. export k from './util.js';  
  7. console.log(k(4)); // returns 16 

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

  1. // in util.js  
  2. export function times(x) {  
  3.   return x * x;  
  4.  
  5. export function plusTwo(number) {  
  6.   return number + 2;  
  7.  
  8. // in app.js  
  9. import { times as multiplication, plusTwo as plus2 } from './util.js'; 

直接这样引入名称: 

  1. import React from 'react'; 

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

在 React 中使用

显然我们已经在 src / App.js 文件中看到了这个,然后在 index.js 文件中看到了导出的 App 组件的呈现方式。 我们暂时忽略 serviceWorker 部分。 

  1. //index.js file  
  2. import React from 'react';  
  3. import ReactDOM from 'react-dom';  
  4. import './index.css';  
  5. import App from './App';  
  6. import * as serviceWorker from './serviceWorker';  
  7. ReactDOM.render(<App />, document.getElementById('root'));  
  8. // If you want your app to work offline and load faster, you can change  
  9. // unregister() to register() below. Note this comes with some pitfalls.  
  10. // Learn more about service workers: http://bit.ly/CRA-PWA  
  11. serviceWorker.unregister(); 

请注意如何从 ./App 目录导入 App ,并省略了 .js 扩展名。 我们只能在导入 JavaScript 文件时省略文件扩展名,但在其他文件中我们必须包含扩展名,例如 .css 。 我们还导入另一个 node 模块 react-dom ,这使我们能够将 React 组件呈现为 HTML元素。

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

总结

React 的优点在于它不会像其他 Web 框架一样在 JavaScript 之上添加任何外部抽象层。 这就是为什么 React 变得非常受 JS 开发人员欢迎的原因。 它只是使用***的 JavaScript 来使构建用户界面更容易和可维护。 在 React 应用程序中,确实有比 React specix 语法更多的 JavaScript ,所以一旦你更好地理解了 JavaScript - 特别是 ES6 - 你就可以自信地编写 React 应用程序了。 但这并不意味着您必须掌握 JavaScript 的所有内容才能开始编写 React 应用程序。 现在去写一个,随着机会的到来,你将成为一个更好的开发者。

感谢阅读,我希望你学到一些新东西:)

 

责任编辑:庞桂玉 来源: segmentfault
相关推荐

2014-07-21 10:45:46

JavaScript

2017-04-06 10:27:01

JavaScript基础Java

2018-08-22 09:14:26

前端JavascriptReact

2019-08-28 07:28:13

React应用程序代码

2009-09-22 11:18:11

2022-07-29 09:17:46

JavaScriptReactJS学习

2017-12-06 08:27:06

程序员职业技术

2018-11-06 07:30:00

2022-10-20 10:29:00

元宇宙Meta虚拟

2020-06-12 08:34:37

React开发工具

2022-10-08 00:01:00

ssrvuereact

2024-01-16 08:05:53

2020-07-20 08:23:04

Redis分布式系统

2021-09-18 10:00:24

ReactJavaScript前端

2022-09-15 17:08:20

JavaScripWeb开发

2017-06-30 12:53:50

Javascript框架Vue vs Reac

2014-02-01 21:31:10

JavaScriptJS框架

2018-10-28 16:14:55

Reactreact.js前端

2022-02-25 08:00:00

编程ReactTypescript

2020-10-13 06:56:19

JavaScript异常类型开发
点赞
收藏

51CTO技术栈公众号