国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

你要的 React 面試知識(shí)點(diǎn),都在這了

klinson / 2660人閱讀

摘要:是流行的框架之一,在年及以后將會(huì)更加流行。于年首次發(fā)布,多年來廣受歡迎。下面是另一個(gè)名為的高階函數(shù)示例,該函數(shù)接受另外兩個(gè)函數(shù),分別是和。將所有較小的函數(shù)組合成更大的函數(shù),最終,得到一個(gè)應(yīng)用程序,這稱為組合。

React是流行的javascript框架之一,在2019年及以后將會(huì)更加流行。React于2013年首次發(fā)布,多年來廣受歡迎。它是一個(gè)聲明性的、基于組件的、用于構(gòu)建用戶界面的高效javascript庫(kù)。

想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!

以下是面試前必須了解的話題。

什么是聲明式編程

聲明式編程 vs 命令式編程

什么是函數(shù)式編程

什么是組件設(shè)計(jì)模式

React 是什么

React 和 Angular 有什么不同

什么是虛擬DOM及其工作原理

什么是JSX

組件和不同類型

Props 和 State

什么是 PropTypes

如何更新狀態(tài)和不更新狀態(tài)

組件生命周期方法

超越繼承的組合

如何在React中應(yīng)用樣式

什么是Redux及其工作原理

什么是React路由器及其工作原理

什么是錯(cuò)誤邊界

什么是 Fragments

什么是傳送門(Portals)

什么是 Context

什么是 Hooks

如何提高性能

如何在重新加載頁(yè)面時(shí)保留數(shù)據(jù)

如何從React中調(diào)用API

總結(jié)

什么是聲明式編程

聲明式編程是一種編程范式,它關(guān)注的是你要做什么,而不是如何做。它表達(dá)邏輯而不顯式地定義步驟。這意味著我們需要根據(jù)邏輯的計(jì)算來聲明要顯示的組件。它沒有描述控制流步驟。聲明式編程的例子有HTML、SQL等

HTML file

// HTML

Declarative Programming

SQL file

select * from studens where firstName = "declarative";

聲明式編程 vs 命令式編程

聲明式編程的編寫方式描述了應(yīng)該做什么,而命令式編程描述了如何做。在聲明式編程中,讓編譯器決定如何做事情。聲明性程序很容易推理,因?yàn)榇a本身描述了它在做什么。

下面是一個(gè)例子,數(shù)組中的每個(gè)元素都乘以 2,我們使用聲明式map函數(shù),讓編譯器來完成其余的工作,而使用命令式,需要編寫所有的流程步驟。

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

// 聲明式
const doubleWithDec = numbers.map(number => number * 2);

console.log(doubleWithDec)

// 命令式
const doubleWithImp = [];
for(let i=0; i
什么是函數(shù)式編程

函數(shù)式編程是聲明式編程的一部分。javascript中的函數(shù)是第一類公民,這意味著函數(shù)是數(shù)據(jù),你可以像保存變量一樣在應(yīng)用程序中保存、檢索和傳遞這些函數(shù)。

函數(shù)式編程有些核心的概念,如下:

不可變性(Immutability)

純函數(shù)(Pure Functions)

數(shù)據(jù)轉(zhuǎn)換(Data Transformations)

高階函數(shù) (Higher-Order Functions)

遞歸

組合

不可變性(Immutability)

不可變性意味著不可改變。 在函數(shù)式編程中,你無法更改數(shù)據(jù),也不能更改。 如果要改變或更改數(shù)據(jù),則必須復(fù)制數(shù)據(jù)副本來更改。

例如,這是一個(gè)student對(duì)象和changeName函數(shù),如果要更改學(xué)生的名稱,則需要先復(fù)制 student 對(duì)象,然后返回新對(duì)象。

在javascript中,函數(shù)參數(shù)是對(duì)實(shí)際數(shù)據(jù)的引用,你不應(yīng)該使用 student.firstName =“testing11”,這會(huì)改變實(shí)際的student 對(duì)象,應(yīng)該使用Object.assign復(fù)制對(duì)象并返回新對(duì)象。

let student = {
    firstName: "testing",
    lastName: "testing",
    marks: 500
}

function changeName(student) {
    // student.firstName = "testing11" //should not do it
    let copiedStudent = Object.assign({}, student);
    copiedStudent.firstName = "testing11";
    return copiedStudent;
}

console.log(changeName(student));

console.log(student);

純函數(shù)

純函數(shù)是始終接受一個(gè)或多個(gè)參數(shù)并計(jì)算參數(shù)并返回?cái)?shù)據(jù)或函數(shù)的函數(shù)。 它沒有副作用,例如設(shè)置全局狀態(tài),更改應(yīng)用程序狀態(tài),它總是將參數(shù)視為不可變數(shù)據(jù)。

我想使用 appendAddress 的函數(shù)向student對(duì)象添加一個(gè)地址。 如果使用非純函數(shù),它沒有參數(shù),直接更改 student 對(duì)象來更改全局狀態(tài)。

使用純函數(shù),它接受參數(shù),基于參數(shù)計(jì)算,返回一個(gè)新對(duì)象而不修改參數(shù)。

let student = {
    firstName: "testing",
    lastName: "testing",
    marks: 500
}

// 非純函數(shù)
function appendAddress() {
    student.address = {streetNumber:"0000", streetName: "first", city:"somecity"};
}

console.log(appendAddress());

// 純函數(shù)
function appendAddress(student) {
    let copystudent = Object.assign({}, student);
    copystudent.address = {streetNumber:"0000", streetName: "first", city:"somecity"};
    return copystudent;
}

console.log(appendAddress(student));

console.log(student);

數(shù)據(jù)轉(zhuǎn)換

我們講了很多關(guān)于不可變性的內(nèi)容,如果數(shù)據(jù)是不可變的,我們?nèi)绾胃淖償?shù)據(jù)。如上所述,我們總是生成原始數(shù)據(jù)的轉(zhuǎn)換副本,而不是直接更改原始數(shù)據(jù)。

再介紹一些 javascript內(nèi)置函數(shù),當(dāng)然還有很多其他的函數(shù),這里有一些例子。所有這些函數(shù)都不改變現(xiàn)有的數(shù)據(jù),而是返回新的數(shù)組或?qū)ο蟆?/p>

let cities = ["irving", "lowell", "houston"];

// we can get the comma separated list
console.log(cities.join(","))
// irving,lowell,houston

// if we want to get cities start with i
const citiesI = cities.filter(city => city[0] === "i");
console.log(citiesI)
// [ "irving" ]

// if we want to capitalize all the cities
const citiesC = cities.map(city => city.toUpperCase());
console.log(citiesC)
// [ "IRVING", "LOWELL", "HOUSTON" ]
高階函數(shù)

高階函數(shù)是將函數(shù)作為參數(shù)或返回函數(shù)的函數(shù),或者有時(shí)它們都有。 這些高階函數(shù)可以操縱其他函數(shù)。

Array.map,Array.filter和Array.reduce是高階函數(shù),因?yàn)樗鼈儗⒑瘮?shù)作為參數(shù)。

const numbers = [10,20,40,50,60,70,80]

const out1 = numbers.map(num => num * 100);
console.log(out1);
// [ 1000, 2000, 4000, 5000, 6000, 7000, 8000 ]

const out2 = numbers.filter(num => num > 50);
console.log(out2);
// [ 60, 70, 80 ]

const out3 = numbers.reduce((out,num) => out + num);
console.log(out3);
// 330

下面是另一個(gè)名為isPersonOld的高階函數(shù)示例,該函數(shù)接受另外兩個(gè)函數(shù),分別是 messageisYoung

const isYoung = age => age < 25;

const message = msg => "He is "+ msg;

function isPersonOld(age, isYoung, message) {
    const returnMessage = isYoung(age)?message("young"):message("old");
    return returnMessage;
}

// passing functions as an arguments
console.log(isPersonOld(13,isYoung,message))
// He is young

遞歸

遞歸是一種函數(shù)在滿足一定條件之前調(diào)用自身的技術(shù)。只要可能,最好使用遞歸而不是循環(huán)。你必須注意這一點(diǎn),瀏覽器不能處理太多遞歸和拋出錯(cuò)誤。

下面是一個(gè)演示遞歸的例子,在這個(gè)遞歸中,打印一個(gè)類似于樓梯的名稱。我們也可以使用for循環(huán),但只要可能,我們更喜歡遞歸。

function printMyName(name, count) {
    if(count <= name.length) {
        console.log(name.substring(0,count));
        printMyName(name, ++count);
    }
}

console.log(printMyName("Bhargav", 1));

/*
B
Bh
Bha
Bhar
Bharg
Bharga
Bhargav
*/

// withotu recursion
var name = "Bhargav"
var output = "";
for(let i=0; i
組合

在React中,我們將功能劃分為小型可重用的純函數(shù),我們必須將所有這些可重用的函數(shù)放在一起,最終使其成為產(chǎn)品。 將所有較小的函數(shù)組合成更大的函數(shù),最終,得到一個(gè)應(yīng)用程序,這稱為組合

實(shí)現(xiàn)組合有許多不同方法。 我們從Javascript中了解到的一種常見方法是鏈接。 鏈接是一種使用點(diǎn)表示法調(diào)用前一個(gè)函數(shù)的返回值的函數(shù)的方法。

這是一個(gè)例子。 我們有一個(gè)name,如果firstNamelastName大于5個(gè)單詞的大寫字母,剛返回,并且打印名稱的名稱和長(zhǎng)度。

const name = "Bhargav Bachina";

const output = name.split(" ")
    .filter(name => name.length > 5)
    .map(val => {
    val = val.toUpperCase();
    console.log("Name:::::"+val);
    console.log("Count::::"+val.length);
    return val;
});

console.log(output)
/*
Name:::::BHARGAV
Count::::7
Name:::::BACHINA
Count::::7
[ "BHARGAV", "BACHINA" ]
*/

在React中,我們使用了不同于鏈接的方法,因?yàn)槿绻?0個(gè)這樣的函數(shù),就很難進(jìn)行鏈接。這里的目的是將所有更簡(jiǎn)單的函數(shù)組合起來生成一個(gè)更高階的函數(shù)。

const name = compose(
    splitmyName,
    countEachName,
    comvertUpperCase,
    returnName
)

console.log(name);

什么是 React

React是一個(gè)簡(jiǎn)單的javascript UI庫(kù),用于構(gòu)建高效、快速的用戶界面。它是一個(gè)輕量級(jí)庫(kù),因此很受歡迎。它遵循組件設(shè)計(jì)模式、聲明式編程范式和函數(shù)式編程概念,以使前端應(yīng)用程序更高效。它使用虛擬DOM來有效地操作DOM。它遵循從高階組件到低階組件的單向數(shù)據(jù)流。

React 與 Angular 有何不同?

Angular是一個(gè)成熟的MVC框架,帶有很多特定的特性,比如服務(wù)、指令、模板、模塊、解析器等等。React是一個(gè)非常輕量級(jí)的庫(kù),它只關(guān)注MVC的視圖部分。

Angular遵循兩個(gè)方向的數(shù)據(jù)流,而React遵循從上到下的單向數(shù)據(jù)流。React在開發(fā)特性時(shí)給了開發(fā)人員很大的自由,例如,調(diào)用API的方式、路由等等。我們不需要包括路由器庫(kù),除非我們需要它在我們的項(xiàng)目。

什么是Virtual DOM及其工作原理

React 使用 Virtual DOM 來更新真正的 DOM,從而提高效率和速度。 我們來詳細(xì)討論這些。

什么是Virtual DOM

瀏覽器遵循HTML指令來構(gòu)造文檔對(duì)象模型(DOM)。當(dāng)瀏覽器加載HTML并呈現(xiàn)用戶界面時(shí),HTML文檔中的所有元素都變成DOM元素。

DOM是從根元素開始的元素層次結(jié)構(gòu)。例如,看看下面的HTML。

This is heading

this is paragraph

This is just a paragraon

This is heading

this is paragraph

This is just a paragraon

This is heading

this is paragraph

This is just a paragraon

當(dāng)在瀏覽器中加載這個(gè)HTML時(shí),所有這些HTML元素都被轉(zhuǎn)換成DOM元素,如下所示

當(dāng)涉及到SPA應(yīng)用程序時(shí),首次加載index.html,并在index.html本身中加載更新后的數(shù)據(jù)或另一個(gè)html。當(dāng)用戶瀏覽站點(diǎn)時(shí),我們使用新內(nèi)容更新相同的index.html。每當(dāng)DOM發(fā)生更改時(shí),瀏覽器都需要重新計(jì)算CSS、進(jìn)行布局并重新繪制web頁(yè)面。

React 使用 Virtual DOM 有效地重建 DOM。 對(duì)于我們來說,這使得DOM操作的一項(xiàng)非常復(fù)雜和耗時(shí)的任務(wù)變得更加容易。 React從開發(fā)人員那里抽象出所有這些,以便在Virtual DOM的幫助下構(gòu)建高效的UI。

虛擬DOM是如何工作的

虛擬DOM只不過是真實(shí) DOM 的 javascript對(duì)象表示。 與更新真實(shí) DOM 相比,更新 javascript 對(duì)象更容易,更快捷。 考慮到這一點(diǎn),讓我們看看它是如何工作的。

React將整個(gè)DOM副本保存為虛擬DOM

每當(dāng)有更新時(shí),它都會(huì)維護(hù)兩個(gè)虛擬DOM,以比較之前的狀態(tài)和當(dāng)前狀態(tài),并確定哪些對(duì)象已被更改。 例如,段落文本更改為更改。

現(xiàn)在,它通過比較兩個(gè)虛擬DOM 差異,并將這些變化更新到實(shí)際DOM

一旦真正的DOM更新,它也會(huì)更新UI

什么是 JSX

JSX是javascript的語法擴(kuò)展。它就像一個(gè)擁有javascript全部功能的模板語言。它生成React元素,這些元素將在DOM中呈現(xiàn)。React建議在組件使用JSX。在JSX中,我們結(jié)合了javascript和HTML,并生成了可以在DOM中呈現(xiàn)的react元素。

下面是JSX的一個(gè)例子。我們可以看到如何將javascript和HTML結(jié)合起來。如果HTML中包含任何動(dòng)態(tài)變量,我們應(yīng)該使用表達(dá)式{}

import React from "react";

export const Header = () => {

    const heading = "TODO App"

    return(
        

{heading}

) }
組件和不同類型

React 中一切都是組件。 我們通常將應(yīng)用程序的整個(gè)邏輯分解為小的單個(gè)部分。 我們將每個(gè)多帶帶的部分稱為組件。 通常,組件是一個(gè)javascript函數(shù),它接受輸入,處理它并返回在UI中呈現(xiàn)的React元素。

在React中有不同類型的組件。讓我們?cè)敿?xì)看看。

函數(shù)/無狀態(tài)/展示組件

函數(shù)或無狀態(tài)組件是一個(gè)純函數(shù),它可接受接受參數(shù),并返回react元素。這些都是沒有任何副作用的純函數(shù)。這些組件沒有狀態(tài)或生命周期方法,這里有一個(gè)例子。

import React from "react";
import Jumbotron from "react-bootstrap/Jumbotron";

export const Header = () => {
    return(
        
            

TODO App

) }
類/有狀態(tài)組件

類或有狀態(tài)組件具有狀態(tài)和生命周期方可能通過 setState()方法更改組件的狀態(tài)。類組件是通過擴(kuò)展React創(chuàng)建的。它在構(gòu)造函數(shù)中初始化,也可能有子組件,這里有一個(gè)例子。

import React from "react";
import "../App.css";
import { ToDoForm } from "./todoform";
import { ToDolist } from "./todolist";

export class Dashboard extends React.Component {

  constructor(props){
    super(props);

    this.state = {

    }
  }
  
  render() {
    return (
      
); } }
受控組件

受控組件是在 React 中處理輸入表單的一種技術(shù)。表單元素通常維護(hù)它們自己的狀態(tài),而react則在組件的狀態(tài)屬性中維護(hù)狀態(tài)。我們可以將兩者結(jié)合起來控制輸入表單。這稱為受控組件。因此,在受控組件表單中,數(shù)據(jù)由React組件處理。

這里有一個(gè)例子。當(dāng)用戶在 todo 項(xiàng)中輸入名稱時(shí),調(diào)用一個(gè)javascript函數(shù)handleChange捕捉每個(gè)輸入的數(shù)據(jù)并將其放入狀態(tài),這樣就在 handleSubmit中的使用數(shù)據(jù)。

import React from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";

export class ToDoForm extends React.Component {
    constructor(props) {
      super(props);
      this.state = {value: ""};
  
      this.handleChange = this.handleChange.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
    }
  
    handleChange(event) {
      this.setState({value: event.target.value});
    }
  
    handleSubmit(event) {
      alert("A name was submitted: " + this.state.value);
      event.preventDefault();
    }
  
    render() {
      return (
          
Item
); } }
非受控組件

大多數(shù)情況下,建議使用受控組件。有一種稱為非受控組件的方法可以通過使用Ref來處理表單數(shù)據(jù)。在非受控組件中,Ref用于直接從DOM訪問表單值,而不是事件處理程序。

我們使用Ref構(gòu)建了相同的表單,而不是使用React狀態(tài)。 我們使用React.createRef() 定義Ref并傳遞該輸入表單并直接從handleSubmit方法中的DOM訪問表單值。

import React from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";

export class ToDoForm extends React.Component {
    constructor(props) {
      super(props);
      this.state = {value: ""};
      this.input = React.createRef();
  
      this.handleSubmit = this.handleSubmit.bind(this);
    }
  
    handleSubmit(event) {
      alert("A name was submitted: " + this.input.current.value);
      event.preventDefault();
    }
  
    render() {
      return (
          
Item
); } }
容器組件

容器組件是處理獲取數(shù)據(jù)、訂閱 redux 存儲(chǔ)等的組件。它們包含展示組件和其他容器組件,但是里面從來沒有html。

高階組件

高階組件是將組件作為參數(shù)并生成另一個(gè)組件的組件。 Redux connect是高階組件的示例。 這是一種用于生成可重用組件的強(qiáng)大技術(shù)。

Props 和 State

Props 是只讀屬性,傳遞給組件以呈現(xiàn)UI和狀態(tài),我們可以隨時(shí)間更改組件的輸出。

下面是一個(gè)類組件的示例,它在構(gòu)造函數(shù)中定義了propsstate,每當(dāng)使用this.setState() 修改狀態(tài)時(shí),將再次調(diào)用 render( ) 函數(shù)來更改UI中組件的輸出。

import React from "react";
import "../App.css";

export class Dashboard extends React.Component {

  constructor(props){
    super(props);

    this.state = {
        name: "some name"
    }
  }

  render() {

    // reading state
    const name = this.state.name;

    //reading props
    const address = this.props.address;

    return (
      
{name} {address}
); } }
什么是PropTypes

隨著時(shí)間的推移,應(yīng)用程序會(huì)變得越來越大,因此類型檢查非常重要。PropTypes為組件提供類型檢查,并為其他開發(fā)人員提供很好的文檔。如果react項(xiàng)目不使用 Typescript,建議為組件添加 PropTypes

如果組件沒有收到任何 props,我們還可以為每個(gè)組件定義要顯示的默認(rèn) props。這里有一個(gè)例子。UserDisplay有三個(gè) prop:nameaddressage,我們正在為它們定義默認(rèn)的props 和 prop類型。

import React from "react";
import PropTypes from "prop-types";

export const UserDisplay = ({name, address, age}) => {

    UserDisplay.defaultProps = {
        name: "myname",
        age: 100,
        address: "0000 onestreet"
    };

    return (
        <>
            
Name:
{name}
Address:
{address}
Age:
{age}
) } UserDisplay.propTypes = { name: PropTypes.string.isRequired, address: PropTypes.objectOf(PropTypes.string), age: PropTypes.number.isRequired }
如何更新狀態(tài)以及如何不更新

你不應(yīng)該直接修改狀態(tài)。可以在構(gòu)造函數(shù)中定義狀態(tài)值。直接使用狀態(tài)不會(huì)觸發(fā)重新渲染。React 使用this.setState()時(shí)合并狀態(tài)。

//  錯(cuò)誤方式
this.state.name = "some name"
//  正確方式
this.setState({name:"some name"})

使用this.setState()的第二種形式總是更安全的,因?yàn)楦碌膒rops和狀態(tài)是異步的。這里,我們根據(jù)這些 props 更新狀態(tài)。

// 錯(cuò)誤方式
this.setState({
    timesVisited: this.state.timesVisited + this.props.count
})
// 正確方式
this.setState((state, props) => {
    timesVisited: state.timesVisited + props.count
});
組件生命周期方法

組件在進(jìn)入和離開DOM時(shí)要經(jīng)歷一系列生命周期方法,下面是這些生命周期方法。

componentWillMount()

在渲染前調(diào)用,在客戶端也在服務(wù)端,它只發(fā)生一次。

componentDidMount()

在第一次渲染后調(diào)用,只在客戶端。之后組件已經(jīng)生成了對(duì)應(yīng)的DOM結(jié)構(gòu),可以通過this.getDOMNode()來進(jìn)行訪問。 如果你想和其他JavaScript框架一起使用,可以在這個(gè)方法中調(diào)用setTimeout, setInterval或者發(fā)送AJAX請(qǐng)求等操作(防止異部操作阻塞UI)。

componentWillReceiveProps()

在組件接收到一個(gè)新的 prop (更新后)時(shí)被調(diào)用。這個(gè)方法在初始化render時(shí)不會(huì)被調(diào)用。

shouldComponentUpdate()

返回一個(gè)布爾值。在組件接收到新的props或者state時(shí)被調(diào)用。在初始化時(shí)或者使用forceUpdate時(shí)不被調(diào)用。 可以在你確認(rèn)不需要更新組件時(shí)使用。

componentWillUpdate()

在組件接收到新的props或者state但還沒有render時(shí)被調(diào)用。在初始化時(shí)不會(huì)被調(diào)用。

componentDidUpdate()

在組件完成更新后立即調(diào)用。在初始化時(shí)不會(huì)被調(diào)用。

componentWillUnMount()

件從 DOM 中移除的時(shí)候立刻被調(diào)用。

getDerivedStateFromError()

這個(gè)生命周期方法在ErrorBoundary類中使用。實(shí)際上,如果使用這個(gè)生命周期方法,任何類都會(huì)變成ErrorBoundary。這用于在組件樹中出現(xiàn)錯(cuò)誤時(shí)呈現(xiàn)回退UI,而不是在屏幕上顯示一些奇怪的錯(cuò)誤。

componentDidCatch()

這個(gè)生命周期方法在ErrorBoundary類中使用。實(shí)際上,如果使用這個(gè)生命周期方法,任何類都會(huì)變成ErrorBoundary。這用于在組件樹中出現(xiàn)錯(cuò)誤時(shí)記錄錯(cuò)誤。

超越繼承的組合

在React中,我們總是使用組合而不是繼承。我們已經(jīng)在函數(shù)式編程部分討論了什么是組合。這是一種結(jié)合簡(jiǎn)單的可重用函數(shù)來生成高階組件的技術(shù)。下面是一個(gè)組合的例子,我們?cè)?dashboard 組件中使用兩個(gè)小組件todoFormtodoList

import React from "react";
import "../App.css";
import { ToDoForm } from "./todoform";
import { ToDolist } from "./todolist";

export class Dashboard extends React.Component {

  render() {
    return (
      
); } }
如何在React中應(yīng)用樣式

將樣式應(yīng)用于React組件有三種方法。

外部樣式表

在此方法中,你可以將外部樣式表導(dǎo)入到組件使用類中。 但是你應(yīng)該使用className而不是class來為React元素應(yīng)用樣式, 這里有一個(gè)例子。

import React from "react";
import "./App.css";
import { Header } from "./header/header";
import { Footer } from "./footer/footer";
import { Dashboard } from "./dashboard/dashboard";
import { UserDisplay } from "./userdisplay";

function App() {
  return (
    
); } export default App;
內(nèi)聯(lián)樣式

在這個(gè)方法中,我們可以直接將 props 傳遞給HTML元素,屬性為style。這里有一個(gè)例子。這里需要注意的重要一點(diǎn)是,我們將javascript對(duì)象傳遞給style,這就是為什么我們使用 backgroundColor 而不是CSS方法backbackground -color

import React from "react";

export const Header = () => {

    const heading = "TODO App"

    return(
        

{heading}

) }
定義樣式對(duì)象并使用它

因?yàn)槲覀儗avascript對(duì)象傳遞給style屬性,所以我們可以在組件中定義一個(gè)style對(duì)象并使用它。下面是一個(gè)示例,你也可以將此對(duì)象作為 props 傳遞到組件樹中。

import React from "react";

const footerStyle = {
    width: "100%",
    backgroundColor: "green",
    padding: "50px",
    font: "30px",
    color: "white",
    fontWeight: "bold"
}

export const Footer = () => {
    return(
        
All Rights Reserved 2019
) }
什么是Redux及其工作原理

Redux 是 React的一個(gè)狀態(tài)管理庫(kù),它基于flux。 Redux簡(jiǎn)化了React中的單向數(shù)據(jù)流。 Redux將狀態(tài)管理完全從React中抽象出來。

它是如何工作的

在React中,組件連接到 redux ,如果要訪問 redux,需要派出一個(gè)包含 id和負(fù)載(payload) 的 action。action 中的 payload 是可選的,action 將其轉(zhuǎn)發(fā)給 Reducer。

當(dāng)reducer收到action時(shí),通過 swithc...case 語法比較 actiontype。 匹配時(shí),更新對(duì)應(yīng)的內(nèi)容返回新的 state

當(dāng)Redux狀態(tài)更改時(shí),連接到Redux的組件將接收新的狀態(tài)作為props。當(dāng)組件接收到這些props時(shí),它將進(jìn)入更新階段并重新渲染 UI。

Redux 循環(huán)細(xì)節(jié)

讓我們?cè)敿?xì)看看整個(gè)redux 循環(huán)細(xì)節(jié)。

Action: Action 只是一個(gè)簡(jiǎn)單的json對(duì)象,type 和有payload作為鍵。type 是必須要有的,payload是可選的。下面是一個(gè) action 的例子。

// action

{ 
  type:"SEND_EMAIL", 
  payload: data
};

Action Creators:這些是創(chuàng)建Actions的函數(shù),因此我們?cè)谂砂l(fā)action時(shí)不必在組件中手動(dòng)編寫每個(gè) action。 以下是 action creator 的示例。

// action creator

export function sendEamil(data) {
    return { type:"SEND_EMAIL", payload: data};
}

Reducers:Reducers 是純函數(shù),它將 action和當(dāng)前 state 作為參數(shù),計(jì)算必要的邏輯并返回一個(gè)新r的state。 這些 Reducers 沒有任何副作用。 它不會(huì)改變 state 而是總是返回 state

export default function emailReducer(state = [], action){
 
  switch(action.type) {
      case "SEND_EMAIL":  return Object.assign({}, state, {
       email: action.payload
      });
      default: return state;
  }
}
組件如何與 redux 進(jìn)行連接

mapStateToProps:此函數(shù)將state映射到 props 上,因此只要state發(fā)生變化,新 state 會(huì)重新映射到 props。 這是訂閱store的方式。

mapDispatchToProps:此函數(shù)用于將 action creators 綁定到你的props 。以便我們可以在第12行中使用This . props.actions.sendemail()來派發(fā)一個(gè)動(dòng)作。

connectbindActionCreators來自 redux。 前者用于連接 store ,如第22行,后者用于將 action creators 綁定到你的 props ,如第20行。

// import connect
import { connect } from "react-redux"
import { bindActionCreators } from "redux"

// import action creators
import * as userActions from "../../../actions/userActions";

export class User extends React.Component {
  
    handleSubmit() {
        // dispatch an action
        this.props.actions.sendEmail(this.state.email);
    }
  
}

// you are mapping you state props
const mapStateToProps = (state, ownProps) => ({user: state.user})
// you are binding your action creators to your props
const mapDispatchToProps = (dispatch) => ({actions: bindActionCreators(userActions, dispatch)})

export default connect(mapStateToProps, mapDispatchToProps)(User);


什么是 React Router Dom 及其工作原理

react-router-dom是應(yīng)用程序中路由的庫(kù)。 React庫(kù)中沒有路由功能,需要多帶帶安裝react-router-dom

react-router-dom 提供兩個(gè)路由器BrowserRouterHashRoauter。前者基于rul的pathname段,后者基于hash段。

 前者:http://127.0.0.1:3000/article/num1

 后者:http://127.0.0.1:3000/#/article/num1(不一定是這樣,但#是少不了的)
react-router-dom 組件

BrowserRouterHashRouter 是路由器。

Route 用于路由匹配。

Link 組件用于在應(yīng)用程序中創(chuàng)建鏈接。 它將在HTML中渲染為錨標(biāo)記。

NavLink是突出顯示當(dāng)前活動(dòng)鏈接的特殊鏈接。

Switch 不是必需的,但在組合路由時(shí)很有用。

Redirect 用于強(qiáng)制路由重定向

下面是組件中的LinkNavLinkRedirect 的例子

// normal link
Home

// link which highlights currentlu active route with the given class name

  React


// you can redirect to this url

以下是 react router 組件的示例。 如果你查看下面的示例,我們將匹配路徑并使用SwitchRoute呈現(xiàn)相應(yīng)的組件。

import React from "react"
// import react router DOM elements
import { Switch, Route, Redirect } from "react-router-dom"
import ComponentA from "../common/compa"
import ComponentB from "../common/compb"
import ComponentC from "../common/compc"
import ComponentD from "../common/compd"
import ComponentE from "../common/compe"


const Layout = ({ match }) => {
    return(
        
)} export default Layout
什么是錯(cuò)誤邊界

在 React 中,我們通常有一個(gè)組件樹。如果任何一個(gè)組件發(fā)生錯(cuò)誤,它將破壞整個(gè)組件樹。沒有辦法捕捉這些錯(cuò)誤,我們可以用錯(cuò)誤邊界優(yōu)雅地處理這些錯(cuò)誤。

錯(cuò)誤邊界有兩個(gè)作用

如果發(fā)生錯(cuò)誤,顯示回退UI

記錄錯(cuò)誤

下面是ErrorBoundary類的一個(gè)例子。如果類實(shí)現(xiàn)了 getDerivedStateFromErrorcomponentDidCatch 這兩個(gè)生命周期方法的任何一下,,那么這個(gè)類就會(huì)成為ErrorBoundary。前者返回{hasError: true}來呈現(xiàn)回退UI,后者用于記錄錯(cuò)誤。

import React from "react"

export class ErrorBoundary extends React.Component {
    constructor(props) {
      super(props);
      this.state = { hasError: false };
    }
  
    static getDerivedStateFromError(error) {
      // Update state so the next render will show the fallback UI.
      return { hasError: true };
    }
  
    componentDidCatch(error, info) {
      // You can also log the error to an error reporting service
      console.log("Error::::", error);
    }
  
    render() {
      if (this.state.hasError) {
        // You can render any custom fallback UI
        return 

OOPS!. WE ARE LOOKING INTO IT.

; } return this.props.children; } }

以下是我們?nèi)绾卧谄渲幸粋€(gè)組件中使用ErrorBoundary。使用ErrorBoundary類包裹 ToDoFormToDoList。 如果這些組件中發(fā)生任何錯(cuò)誤,我們會(huì)記錄錯(cuò)誤并顯示回退UI。

import React from "react";
import "../App.css";
import { ToDoForm } from "./todoform";
import { ToDolist } from "./todolist";
import { ErrorBoundary } from "../errorboundary";

export class Dashboard extends React.Component {

  render() {
    return (
      
); } }
什么是 Fragments

在React中,我們需要有一個(gè)父元素,同時(shí)從組件返回React元素。有時(shí)在DOM中添加額外的節(jié)點(diǎn)會(huì)很煩人。使用 Fragments,我們不需要在DOM中添加額外的節(jié)點(diǎn)。我們只需要用 React.Fragment 或才簡(jiǎn)寫 <> 來包裹內(nèi)容就行了。如下 所示:

 // Without Fragments   
return (
    
) // With Fragments return ( ) // shorthand notation Fragments return ( <> )
什么是傳送門(Portals)

默認(rèn)情況下,所有子組件都在UI上呈現(xiàn),具體取決于組件層次結(jié)構(gòu)。Portal 提供了一種將子節(jié)點(diǎn)渲染到存在于父組件以外的 DOM 節(jié)點(diǎn)的優(yōu)秀的方案。

這里有一個(gè)例子。默認(rèn)情況下,父組件在DOM層次結(jié)構(gòu)中有子組件。

我們可以將 children 組件移出parent 組件并將其附加 idsomeid 的 Dom 節(jié)點(diǎn)下。

首先,獲取 id 為 someid,我們?cè)赾onstrcutorand中創(chuàng)建一個(gè)元素div,將child附加到componentDidMount中的someRoot。 最后,我們?cè)赗eactDOM.createPortal(this.props.childen),domnode的幫助下將子節(jié)點(diǎn)傳遞給該特定DOM節(jié)點(diǎn)。

首先,先獲取 id 為someid DOM元素,接著在構(gòu)造函數(shù)中創(chuàng)建一個(gè)元素div,在 componentDidMount方法中將 someRoot 放到 div 中 。 最后,通過
ReactDOM.createPortal(this.props.childen), domnode)children 傳遞到對(duì)應(yīng)的節(jié)點(diǎn)下。

const someRoot = document.getElementById("someid");

class Modal extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement("div");
  }

  componentDidMount() {
    someRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    someRoot.removeChild(this.el);
  }

  render() {
    return ReactDOM.createPortal(
      this.props.children,
      this.el,
    );
  }
}

什么是上下文

有時(shí)我們必須將props 傳遞給組件樹,即使所有中間組件都不需要這些props 。上下文是一種傳遞props 的方法,而不用在每一層傳遞組件樹。

什么是 Hooks

Hooks 是React版本16.8中的新功能。 請(qǐng)記住,我們不能在函數(shù)組件中使用state ,因?yàn)樗鼈儾皇穷惤M件。Hooks 讓我們?cè)诤瘮?shù)組件中可以使用state 和其他功能。

目前沒有重大變化,我們不必放棄類組件。

Hook 不會(huì)影響你對(duì) React 概念的理解。 恰恰相反,Hook 為已知的 React 概念提供了更直接的 API:props, state,context,refs 以及生命周期。稍后我們將看到,Hook 還提供了一種更強(qiáng)大的方式來組合他們。

我們可以使用一些鉤子,例如useState,useEffect,useContext,useReducer等。

下面是 Hooks 的基本規(guī)則

Hooks 應(yīng)該在外層使用,不應(yīng)該在循環(huán),條件或嵌套函數(shù)中使用

Hooks 應(yīng)該只在函數(shù)組件中使用。

讓我們看一個(gè)例子來理解 hooks。 這是一個(gè)函數(shù)組件,它采用props并在UI上顯示這些props。 在useState鉤子的幫助下,我們將這個(gè)函數(shù)組件轉(zhuǎn)換為有狀態(tài)組件。 首先,我們?cè)诘?行定義狀態(tài),這相當(dāng)于

constructor(props) {
 super(props);
 this.state = {
     name:"myname", age:10, address:"0000 one street"
 }
}

useState返回兩個(gè)項(xiàng),一個(gè)是user,另一個(gè)是setUser函數(shù)。 user 是一個(gè)可以在沒有 this關(guān)鍵字的情況下直接使用的對(duì)象,setUser是一個(gè)可以用來設(shè)置用戶點(diǎn)擊第21行按鈕的狀態(tài)的函數(shù),該函數(shù)等效于以下內(nèi)容。

this.setState({name:"name changed"})


    1  import React, { useState } from "react";
    2
    3  export const UserDisplay = ({name, address, age}) => {
    4
    5    const [user, setUser] = useState({ name: "myname", age: 10, address: "0000 onestreet" });
    6
    7    return (
    8        <>
    9            
10
Name:
11
{user.name}
12
13
14
Address:
15
{user.address}
16
17
18
Age:
19
{user.age}
20
21 24 25 ) 26 }
如何提高性能

我們可以通過多種方式提高應(yīng)用性能,以下這些比較重要:

適當(dāng)?shù)厥褂?b>shouldComponentUpdate生命周期方法。 它避免了子組件的不必要的渲染。 如果樹中有100個(gè)組件,則不重新渲染整個(gè)組件樹來提高應(yīng)用程序性能。

使用create-react-app來構(gòu)建項(xiàng)目,這會(huì)創(chuàng)建整個(gè)項(xiàng)目結(jié)構(gòu),并進(jìn)行大量?jī)?yōu)化。

不可變性是提高性能的關(guān)鍵。不要對(duì)數(shù)據(jù)進(jìn)行修改,而是始終在現(xiàn)有集合的基礎(chǔ)上創(chuàng)建新的集合,以保持盡可能少的復(fù)制,從而提高性能。

在顯示列表或表格時(shí)始終使用 Keys,這會(huì)讓 React 的更新速度更快

代碼分離是將代碼插入到多帶帶的文件中,只加載模塊或部分所需的文件的技術(shù)。

如何在重新加載頁(yè)面時(shí)保留數(shù)據(jù)

單頁(yè)應(yīng)用程序首先在DOM中加載index.html,然后在用戶瀏覽頁(yè)面時(shí)加載內(nèi)容,或者從同一index.html中的后端API獲取任何數(shù)據(jù)。

如果通過點(diǎn)擊瀏覽器中的重新加載按鈕重新加載頁(yè)面index.html,整個(gè)React應(yīng)用程序?qū)⒅匦录虞d,我們將丟失應(yīng)用程序的狀態(tài)。 如何保留應(yīng)用狀態(tài)?

每當(dāng)重新加載應(yīng)用程序時(shí),我們使用瀏覽器localstorage來保存應(yīng)用程序的狀態(tài)。我們將整個(gè)存儲(chǔ)數(shù)據(jù)保存在localstorage中,每當(dāng)有頁(yè)面刷新或重新加載時(shí),我們從localstorage加載狀態(tài)。

如何在React進(jìn)行API調(diào)用

我們使用redux-thunk在React中調(diào)用API。因?yàn)?b>reduce是純函數(shù),所以沒有副作用,比如調(diào)用API。

因此,我們必須使用redux-thunk從 action creators 那里進(jìn)行 API 調(diào)用。Action creator 派發(fā)一個(gè)action,將來自API的數(shù)據(jù)放入action 的 payload 中。Reducers 接收我們?cè)谏厦娴?b>redux循環(huán)中討論的數(shù)據(jù),其余的過程也是相同的。

redux-thunk是一個(gè)中間件。一旦它被引入到項(xiàng)目中,每次派發(fā)一個(gè)action時(shí),都會(huì)通過thunk傳遞。如果它是一個(gè)函數(shù),它只是等待函數(shù)處理并返回響應(yīng)。如果它不是一個(gè)函數(shù),它只是正常處理。

這里有一個(gè)例子。sendEmailAPI是從組件中調(diào)用的函數(shù),它接受一個(gè)數(shù)據(jù)并返回一個(gè)函數(shù),其中dispatch作為參數(shù)。我們使用redux-thunk調(diào)用API apiservice,并等待收到響應(yīng)。一旦接收到響應(yīng),我們就使用payload 派發(fā)一個(gè)action

import apiservice from "../services/apiservice";

export function sendEmail(data) {
    return { type:"SEND_EMAIL", payload: data };
}

export function sendEmailAPI(email) {
    return function(dispatch) {
        return apiservice.callAPI(email).then(data => {
            dispatch(sendEmail(data));
        });
    }
}


總結(jié)

要想有把握的面試,必須充分了解上述所有主題。 即使你目前正在使用React,理解這些概念也能增強(qiáng)你在職場(chǎng)中信心。

代碼部署后可能存在的BUG沒法實(shí)時(shí)知道,事后為了解決這些BUG,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。

交流

這篇來來回回整理了快五天,大家給個(gè)贊唄!

干貨系列文章匯總?cè)缦拢X得不錯(cuò)點(diǎn)個(gè)Star,歡迎 加群 互相學(xué)習(xí)。

https://github.com/qq44924588...

我是小智,公眾號(hào)「大遷世界」作者,對(duì)前端技術(shù)保持學(xué)習(xí)愛好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!

關(guān)注公眾號(hào),后臺(tái)回復(fù)福利,即可看到福利,你懂的。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/104279.html

相關(guān)文章

  • 分享一個(gè)比較完整的Vue2+項(xiàng)目供大家交流學(xué)習(xí)

    摘要:分享一個(gè)比較完整的項(xiàng)目供大家交流學(xué)習(xí),這個(gè)項(xiàng)目的英文簡(jiǎn)介項(xiàng)目地址在線演示翻譯過來呢就是一個(gè)涉及面較廣的使用豆瓣作為數(shù)據(jù)源的。 分享一個(gè)比較完整的Vue2+項(xiàng)目供大家交流學(xué)習(xí),這個(gè)項(xiàng)目的英文簡(jiǎn)介:Awesome douban DEMO created with Vue2.x + Vuex + Vue-router + vue-resource 項(xiàng)目地址:https://github.co...

    Charlie_Jade 評(píng)論0 收藏0
  • 2018年, 我的前端面試復(fù)盤

    摘要:技術(shù)一面一面主要考察基礎(chǔ),有些會(huì)有技術(shù)筆試,比如騰訊,。騰訊的面試官就很喜歡問,安全,瀏覽器緩存方面的問題,計(jì)算機(jī)基礎(chǔ),但是要懂為什么。 這篇文章簡(jiǎn)單總結(jié)下2018年內(nèi)我的一些前端面試經(jīng)歷, 在這簡(jiǎn)單分享一下,希望對(duì)大家有所啟發(fā)。 樓主在深圳,畢業(yè)兩年。面的主要是深圳的幾家公司。 包括: 騰訊, 螞蟻金服, Lazada, Shopee, 有贊 等 。 樓主在準(zhǔn)備面試前, 想著復(fù)習(xí)一...

    Yujiaao 評(píng)論0 收藏0
  • 優(yōu)秀文章收藏(慢慢消化)持續(xù)更新~

    摘要:整理收藏一些優(yōu)秀的文章及大佬博客留著慢慢學(xué)習(xí)原文協(xié)作規(guī)范中文技術(shù)文檔協(xié)作規(guī)范阮一峰編程風(fēng)格凹凸實(shí)驗(yàn)室前端代碼規(guī)范風(fēng)格指南這一次,徹底弄懂執(zhí)行機(jī)制一次弄懂徹底解決此類面試問題瀏覽器與的事件循環(huán)有何區(qū)別筆試題事件循環(huán)機(jī)制異步編程理解的異步 better-learning 整理收藏一些優(yōu)秀的文章及大佬博客留著慢慢學(xué)習(xí) 原文:https://www.ahwgs.cn/youxiuwenzhan...

    JeOam 評(píng)論0 收藏0
  • 需要知道的JS的日期知識(shí)都在這了

    摘要:實(shí)際上是格林威治標(biāo)準(zhǔn)時(shí)間的同義詞默認(rèn)情況下,中的幾乎每個(gè)日期方法除了一個(gè)都是本地時(shí)間。如果你住在格林威治標(biāo)準(zhǔn)時(shí)間晚的的地區(qū),你會(huì)得到一個(gè)日期是月日。需要知道對(duì)象日期方法。 為了保證的可讀性,本文采用意譯而非直譯。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! JS中的 Date 很奇怪。當(dāng)我們需要處理日期和時(shí)間的時(shí)候比較麻煩,經(jīng)常借助像date-fns和 Mom...

    testbird 評(píng)論0 收藏0
  • 2019-我的前端面試

    摘要:先說下我面試情況,我一共面試了家公司。篇在我面試的眾多公司里,只有同城的面問到相關(guān)問題,其他公司壓根沒問。我自己回答的是自己開發(fā)組件面臨的問題。完全不用擔(dān)心對(duì)方到時(shí)候打電話核對(duì)的問題。 2019的5月9號(hào),離發(fā)工資還有1天的時(shí)候,我的領(lǐng)導(dǎo)親切把我叫到辦公室跟我說:阿郭,我們公司要倒閉了,錢是沒有的啦,為了不耽誤你,你趕緊出去找工作吧。聽到這話,我虎軀一震,這已經(jīng)是第2個(gè)月沒工資了。 公...

    iKcamp 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<