爲了避免浪費你們的寶貴時間,在開頭申明一下,這篇文章針對的閱讀對象是:沒有寫過 React
或者剛剛纔接觸 React
而且對於 ES6
的語法不太瞭解的同窗,這是一篇基礎入門的文章,在一開始我並無準備翻譯一篇這樣的基礎文章,可是在閱讀徹底文以後,我想起本身剛開始學習 React
時的迷茫,ES6
有那麼多,我須要掌握多少呢?對於一個急於上手 React
寫代碼的人來講,這篇文章告訴你最基本要掌握的知識,讓你快速的寫起來。可是後期的提升,仍舊須要去夯實 Javascript
的基礎。javascript
在理想的狀態下,你能夠在深刻了解React以前瞭解 JavaScript
和Web
開發的全部知識。 不幸的是,咱們生活在一個不完美的世界,因此在 React
以前把全部的JavaScript
都咀嚼一遍只會讓你舉步維艱。 若是你已經擁有一些 JavaScript
經驗,那麼在 React
以前你須要學習的只是實際用於開發 React
應用程序的 JavaScript
功能。 在學習 React
以前你應該學會的JavaScript
的知識點:css
ES6
類let
/ const
聲明變量Map
和 filter
ES6
模塊系統這是你將在 80%
的時間內使用的20%
的 JavaScript
新特性,所以在本文中,我將幫助你學習全部這些特性。前端
React
應用程序的探索開始學習 React
的常見狀況是運行 create-react-app
包,它會設置運行 React
所需的一切。 該過程完成以後,打開 src / app.js
這裏給咱們展現了整個應用程序中惟一的 React
類:java
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
,那麼你可能認爲這個 class
語句是 React
的一個特性。 實際上這是 ES6
的一個新特性,這就是爲何正確學習 ES6
可讓你更好地理解 React
代碼。 咱們將從 ES6
的類開始。node
ES6
的類ES6
引入了 class
語法,相似於 Java
或 Python
等 OO
(面向對象) 語言。 ES6
中的基本類以下所示:react
class Developer {
constructor(name){
this.name = name;
}
hello(){
return 'Hello World! I am ' + this.name + ' and I am a web developer';
}
}
複製代碼
class
語法後跟一個可用於建立新對象的標識符(或一個名稱)。 始終在對象初始化中調用構造函數方法。 傳遞給這個對象的任何參數都將傳遞給新對象。 例如:web
var nathan = new Developer('Nathan');
nathan.hello(); // Hello World! I am Nathan and I am a web developer
複製代碼
類能夠定義任意它所需的方法,在這種狀況下,咱們定義了一個返回字符串的 hello
方法。數組
類能夠擴展另外一個類的定義,從該類初始化的新對象將具備這兩個類的全部方法。bash
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.
複製代碼
繼承另外一個類的類,一般稱爲 child
類或 sub
類,而正在擴展的類稱爲 parent
類或 super
類。 子類也能夠覆蓋父類中定義的方法,這意味着它將使用本身定義的新方法來替換父類方法的定義。 例如,讓咱們覆蓋 hello
函數:app
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
複製代碼
就這樣,咱們重寫了 Developer
類中的 hello
方法。
如今咱們瞭解了 ES6
的類和繼承,咱們能夠理解 src / app.js
中定義的 React
類。 這是一個 React
組件,但它實際上只是一個普通的 ES6
類,它繼承了從 React
包導入的 React Component
類的定義。
import React, { Component } from 'react';
class App extends Component {
// class content
render(){
return (
<h1>Hello React!</h1>
)
}
}
複製代碼
這使得咱們可以使用 render()
方法,JSX
,this.state
和其餘方法。 全部這些定義都在Component
類中。 但正如咱們稍後將看到的,class
不是定義 React Component
的惟一方法。 若是你不須要狀態和其餘生命週期方法,則可使用函數。
ES6
中的 let
和 const
來聲明變量由於 JavaScript
的 var
關鍵字是聲明全局的變量,因此在 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
中的使用const HelloWorld = (props) => {
return <h1>{props.hello}</h1>;
}
複製代碼
等同於 ES6
的類組件
class HelloWorld extends Component {
render() {
return (
<h1>{props.hello}</h1>;
);
}
}
複製代碼
在 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
複製代碼
如您所見,咱們將開發人員對象中的 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>;
}
複製代碼
Map
和 filter
雖然本文側重於 ES6
,但須要說起 JavaScript
數組 Map
和 filter
方法,由於它們多是構建 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>
)
}
}
複製代碼
咱們一樣能夠在 render
中篩選數據
<ul>
{users
.filter(user => user.age > 26)
.map(user => <li>{user.name}</li>)
}
</ul>
複製代碼
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
語句:
import React, { Component } from 'react';
複製代碼
在第一行代碼中咱們看到 export default
語句:
export default App;
複製代碼
要理解這些語句,咱們先討論模塊語法。
模塊只是一個 JavaScript
文件,它使用 export
關鍵字導出一個或多個值(能夠是對象,函數或變量)。 首先,在 src
目錄中建立一個名爲 util.js
的新文件
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
export k from './util.js';
console.log(k(4)); // returns 16
複製代碼
可是對於命名導出,必須使用花括號和確切名稱導入。 或者,import可使用別名來避免兩個不一樣的導入具備相同的名稱:
// 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
以獲取相應的包名稱。 所以,若是您要導入本地文件,請不要忘記使用正確的路徑。
顯然咱們已經在 src / App.js
文件中看到了這個,而後在 index.js
文件中看到了導出的 App
組件的呈現方式。 咱們暫時忽略 serviceWorker
部分。
//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(); 複製代碼
請注意如何從 ./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
應用程序。 如今去寫一個,隨着機會的到來,你將成爲一個更好的開發者。 感謝閱讀,我但願你學到一些新東西:)
小冊 你不知道的 Chrome 調試技巧 已經開始預售啦。
歡迎關注公衆號 「前端惡霸」,掃碼關注,會有不少好東西等着你~