2021 年学习 React 的所需要的 JavaScript 基础
在理想的情况中,您可以先了解所有有关 JavaScript 和 web 开发的知识,然后再深入了解React。 但是,我们没有办法这样,如果等你把所有 JavaScript 的知识都掌握了再去学习 React,就会浪费很多时间。 如果您已经有一些使用 JavaScript 的经验,那么在 学习 React 之前您需要学习的只是能够实际应用于开发 React 应用程序的 JavaScript 知识。那些掌握下面这些 JavaScript 知识点,就足够你去学习 React。
- ES6的类
- 声明变量 let/const
- 箭头函数
- 解构赋值
- Map and filter
- ES6模块系统
您将在 80% 的时间内使用 20% 的 JavaScript功能,因此在本教程中,我将帮助您学习所有这些功能。
探索 Create React App 脚手架
在开始学习 React 之前我们都用 create-react-app
这个脚手架来创建 React 应用,它具有运行 React 的一切基础套件。
https://reactjs.org/docs/create-a-new-react-app.html
npx create-react-app my-app
cd my-app
npm start
然后,在该过程完成后,打开 src/app.js
文件,将向我们展示整个应用程序中唯一的 React 类:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
}
export default App;
如果你以前从未学过 ES6,你会认为这个类语句是 React 的一个特性。
这实际上是 ES6 的一个新功能,这就是为什么正确学习 ES6 可以让你更好地理解 React 代码。
我们将从 ES6 课程开始:
ES6 类
ES6 引入了类语法,其使用方式与面向对象语言类似,如 Java 或 python,ES6中的基础类如下所示:
class Developer {
// 构造函数,创建新对象时(new),调用
// name 是参数,可以根据需要,定义多个参数
constructor(name){
this.name = name;
}
// 方法
hello(){
return 'Hello World! I am ' + this.name + ' and I am a web developer';
}
}
class
后面跟着类的名称,这个类(有点像模板)可以用于创建一个新的对象。这个 constructor
就是构造函数,当用这个类创建一个新的对象时就会用这个方法。 传递到该构造函数的任何参数都将传递到新对象。
例如:
// Nathan 会传给 constructor 方法,最终 this.name 等于 Nathan
var nathan = new Developer('Nathan');
nathan.hello(); // Hello World! I am Nathan and I am a web developer
一个类可以根据需要定义尽可能多的方法,在这种情况下,我们有返回字符串的 hello
方法。
类继承
一个类可以继承另一个类,并且从该类初始化的新对象将具有两个类的所有方法。
// ReactDeveloper 继承了 Developer 这个类
class ReactDeveloper extends Developer {
installReact(){
return 'installing React .. Done.';
}
}
// 用子类生成了新对象
var nathan = new ReactDeveloper('Nathan');
// 子类对象 nathan 将具有子类与父类的所有方法
nathan.hello(); // Hello World! I am Nathan and I am a web developer
nathan.installReact(); // installing React .. Done.
继承另一个类的类通常称为子类,被继承的类称为父类或超类。
子类还可以覆盖父类中定义的方法,这意味着它将用定义的新方法替换父类方法。
例如,让我们覆盖 hello 函数:
class ReactDeveloper extends Developer {
installReact(){
return 'installing React .. Done.';
}
// Developer 类也有 hello 方法,这里直接重写覆盖
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
这样,Developer
类中的 hello
方法已被覆盖。
在 React 中使用
现在我们了解了ES6类和继承,我们可以了解 src/app.js
中定义的 React 类. 这是一个 React 组件,但它实际上只是一个普通的 ES6 类,继承了从 react
这个库里导入的 React 组件类。
// 从 react 库导入 React 组件类,还有 Component 类
import React, { Component } from 'react';
// 我们自己定义的组件继承 上面导入的 Component 类
class App extends Component {
// class content
render(){
return (
<h1>Hello React!</h1>
)
}
}
因为我们自己定义的 App 组件继承自从 react
库中导入 Component 类,所以我们也具有 Component 类的一些方法,比如 render()
方法,还有 this.state
这些属性。但是后面你可能会看到,类并不是我们唯一定义组件的方式,如果你不需要 state
(一种状态数据), 还有组件的生命周期方法,你可以用函数来代替类的。
使用 ES6 let 和 const 声明变量
以前都是用 var
关键字在 JavaScript 中声明变量,ES6 中引入了两个新的变量声明:即 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 (
<h1>{greeting}</h1>
)
}
}
由于 greeting
在整个应用程序生命周期中不会改变,我们在这里使用 const
定义它。
箭头函数
箭头函数是一个新的 ES6 特性,在现代代码库中几乎被广泛使用,因为它保持代码简洁和可读。
此语法允许我们使用更短的语法编写函数:
// regular function
const testFunction = function() {
// content..
}
// arrow function
const testFunction = () => {
// content..
}
如果你是一个有经验的 JS 开发人员,从一个常规函数语法转到箭头语法一开始可能会不舒服。
当我学习箭头函数时,我使用了这两个简单的步骤来重写我的函数:
- 删除 function 关键字
- 在 () 之后添加箭头符号 =>
括号仍然用于传递参数,如果只有一个参数,则可以省略括号。
// 两个参数
const testFunction = (firstName, lastName) => {
return firstName+' '+lastName;
}
// 一个参数时可以省略括号
const singleParam = firstName => {
return firstName;
}
隐式返回
如果您的箭头函数只有一行,您可以直接返回值,而不必使用 return
关键字和花括号 {}
// 直接返回,不用写 {} 和 return
const testFunction = () => 'hello there.';
testFunction();
在 React 中使用
创建 React 组件的另一种方法是使用箭头函数。
React 组件箭头函数写法:
const HelloWorld = (props) => {
return <h1>{props.hello}</h1>;
}
相当于 ES6 类组件
class HelloWorld extends Component {
render() {
return (
<h1>{props.hello}</h1>;
);
}
}
在您的 React 应用程序中使用箭头函数使代码更加简洁, 因为它也将从组件中删除 state
的使用。
这种类型的组件被称为无状态功能组件。
你会在许多 React 教程中找到这个名字。
数组和对象的解构分配
ES6中引入的最有用的新语法之一,解构赋值就是简单地复制对象或数组的一部分,并将它们放入命名变量中。
一个简单的例子:
const developer = {
firstName: 'Nathan',
lastName: 'Sebhastian',
developer: true,
age: 25,
}
//destructure developer object
// 从 developer 对象中取出数据的简单写法
const { firstName, lastName } = developer;
console.log(firstName); // returns 'Nathan'
console.log(lastName); // returns 'Sebhastian'
console.log(developer); // returns the object
如您所见,我们将 developer 对象的 firstName
和 lastName
分配给了新变量 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 <h1>{props.hello}</h1>;
}
我们可以简单地立即解构参数:
const HelloWorld = ({ hello }) => {
return <h1>{hello}</h1>;
}
解构数组用于 React 的 useState Hook:
const [user, setUser] = useState('');
Map 和 filter
尽管本教程侧重于 ES6,但需要提及 JavaScript 数组映射和过滤器方法,因为它们可能是构建 React 应用程序时最常用的 ES5 功能之一,尤其是处理数据。
这两种方法更多地用于处理数据。例如,假设从 远程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>
)
}
}
我们还可以过滤渲染中的数据。
<ul>
{users
.filter(user => user.age > 26)
.map(user => <li>{user.name}</li>)
}
</ul>
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 (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
}
export default App;
在代码的第一行,我们看到了导入语句:
import React, { Component } from 'react';
在最后一行,我们看到了导出默认 (export default) 语句:
为了理解这些语句,让我们先讨论一下模块语法。
模块只是一个 JavaScript 文件,它使用 export 关键字导出一个或多个值 (可以是对象、函数或变量)。
首先,在 src
目录中创建一个名为 util.js
的新文件
然后在里面写一个函数,这是 默认导出(export default)
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
导入它
// 从 util.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';
将对根目录下的 node_modules
目录进行 JavaScript 检查以获取相应的包名称。
因此,如果要导入本地文件,请不要忘记使用正确的路径。
在 React 中使用
很明显,我们在 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(<App />, 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();
请注意:从 .js
扩展名导入时,可以忽略扩展名的输写。
import App from './App';
总结
React 最大的好处是它不会像其他 web 框架一样在 JavaScript 之上添加任何外部抽象层,这就是为什么React在JS开发人员中变得非常受欢迎,它只是使用最好的 JavaScript 使构建用户界面更容易和可维护。在一个 React 应用程序中,一旦你掌握好上面所讲的 JavaScript 知识,你就可以自信地编写 React 应用,并成为一个优秀的程序员。
翻译自:Nathan Sebhastian
原文:https://dev.to/nsebhastian/javascript-basics-before-you-learn-react-38en
2021 年学习 React 的所需要的 JavaScript 基础的更多相关文章
- 学习笔记 第十五章 JavaScript基础
第15章 JavaScript基础 [学习重点] 了解JavaScript基础知识 熟悉常量和变量 能够使用表达式和运算符 正确使用语句 能够掌握数据类型和转换的基本方法 正确使用函数.对象.数组 ...
- HTML5学习笔记(十一):JavaScript基础
JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中: <head> <script> alert('He ...
- web前端学习(四)JavaScript学习笔记部分(1)-- JavaScript基础教程
1.JavaScript基础教程 1.1.Javascript基础-介绍.实现.输出 1.1.1.JavaScript是互联网上最流行的脚本语言,这门语言可用于web和HTML,更可广泛用于服务端.p ...
- 从0开始学习react(一)
本人前端小菜鸡一枚,因为公司要重构网站,打算用用react,毕竟一切为了学习(装B)嘛!!! 在学习react之前,看了许多资料,博客,官方文档之类的,可我这记吃不记打的记性,还是需要在这里记录一下, ...
- 正式学习React(五) react-redux源码分析
磨刀不误砍柴工,咱先把react-redux里的工具函数分析一下: 源码点这里 shallowEqual.js export default function shallowEqual(objA, ...
- 正式学习React (七) react-router 源码分析
学习react已经有10来天了,对于react redux react-redux 的使用流程和原理,也已经有一定的了解,在我上一篇的实战项目里,我用到了react-route,其实对它还只是 停留在 ...
- 正式学习React(一) 开始学习之前必读
为什么要加这个必读!因为webpack本身是基于node环境的, 里面会涉及很多路径问题,我们可能对paths怎么写!webpack又是怎么找到这些paths的很迷惑. 本文是我已经写完正式学习Rea ...
- 正式学习 react(三)
有了基础的webpack基础,我们要对react的基本语法进行学习. 我这个教程全部用es6 实现.可能会忽略一些最基本的语法讲解,这些你在官网上或者其他别的地方都比我讲的全. 今天我要讲一下reac ...
- 学习react,动手实现一个小demo(仿知乎问答)
学习react也有一周的时间,最近自己做了个仿知乎问答的小demo,项目源码在github上:https://github.com/yang302/reactQa 使用技术:bower+gulp+re ...
随机推荐
- Python: 捕获正在运行的CMD窗口内容
最近需要捕获已经在运行的CMD窗口内容,并且需要根据指定输出内容来判断下一步的行动(输入指定内容). 尝试了很多次后,想到一个思路: 通过inspect.exe来获取CMD窗口Name信息通过uiau ...
- 关于Java注解(annotation)的简单理解
一.什么是注解? 从 JDK5 开始,Java增加对元数据的支持,也就是注解.简单理解就是代码里的特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部 ...
- poj 3278 Catch That Cow(记忆化广度优先搜索)
题意: 0到N的数轴上,每次可以选择移动到x-1,x+1,2*x,问从n移动到k的最少步数. 思路: 同时遍历三种可能并记忆化入队即可. Tips: n大于等于k时最短步数为n-k. 在移动的过程中可 ...
- c语言实现--单向循环链表操作
1,什么叫单向循环链表.单向循环链表是指在单链表的基础上,表的最后一个元素指向链表头结点,不再是为空. 2,由图可知,单向循环链表的判断条件不再是表为空了,而变成了是否到表头. 3,链表的结点表示 1 ...
- codeforces622E Ants in Leaves (dfs)
Description Tree is a connected graph without cycles. A leaf of a tree is any vertex connected with ...
- Git命令回退代码并同步到远程仓库
git log 找到要回退的commit版本号并复制 git reset --hard [commitid] 本地库版本回退 git push -f origin [branchName] 同步到远端 ...
- VScode 相关
1.F5运行py文件,打开terminal终端的时候总是弹出Powershell窗口,只能在powershell窗口中用命令行运行程序,实在很不方便. 解法:右键Powershell属性,取消使用旧版 ...
- 抓包 127.0.0.1 (loopback) 使用 tcpdump+wireshark
直接使用 wireshark无法抓取 127.0.0.1环回的数据包,一种解决方法是先传到路由器再返回,但这样可能造成拥塞. Linux 先使用tcpdump抓包并输出为二进制文件,然后wiresha ...
- 编写一个c函数,该函数给出一个字节中被置为1的位的个数
请编写一个c函数,该函数给出一个字节中被置为1的位的个数 #include <stdio.h> void fun(char ch) { int i; int temp; int count ...
- Next.js SSR Tutorials
Next.js SSR Tutorials https://codesandbox.io/s/nextjs-demo-h49zt cli $ npx create-next-app ssr-demo- ...