Все точки знаний о React, которые вам нужны, здесь.

JavaScript React.js

Резюме:Вопросы подробные, иллюстрации хорошие.

FundebugПерепечатано с разрешения, авторские права принадлежат оригинальному автору.

React — один из популярных фреймворков javascript, который будет еще более популярен в 2019 году и далее. React был впервые выпущен в 2013 году, и с годами его популярность росла. Это декларативная, основанная на компонентах, эффективная библиотека javascript для создания пользовательских интерфейсов.

Вот темы, которые вы должны знать перед собеседованием.

  • Что такое декларативное программирование
  • Декларативное программирование против императивного программирования
  • Что такое функциональное программирование
  • Что такое шаблон проектирования компонентов
  • что такое Реакт
  • В чем разница между React и Angular
  • Что такое виртуальный DOM и как он работает
  • Что такое JSX
  • Компоненты и различные типы
  • Реквизит и состояния
  • Что такое PropTypes
  • Как обновить состояние и не обновлять состояние
  • Методы жизненного цикла компонентов
  • Комбинация вне наследства
  • Как применять стили в React
  • Что такое Redux и как это работает
  • Что такое React Router и как он работает
  • что такое граница ошибки
  • Что такое фрагменты
  • Что такое порталы
  • Что такое контекст
  • Что такое крючки
  • Как улучшить производительность
  • Как сохранить данные при перезагрузке страницы
  • Как вызвать API из React
  • Суммировать

Что такое декларативное программирование

Декларативное программирование — это парадигма программирования, ориентированная на вас.что делать, вместоКак сделать. Он выражает логику без явного определения шагов. Это означает, что нам нужно объявить компоненты для отображения на основе расчета логики. Он не описывает шаги потока управления. Примерами декларативного программирования являются HTML, SQL и т. д.

HTML file

// HTML
<div>
  <p>Declarative Programming</p>
</div>

SQL file

select * from studens where firstName = 'declarative';

Декларативное программирование против императивного программирования

Декларативное программирование описывает, как это сделать, а императивное программирование описывает, как это сделать. В декларативном программировании пусть компилятор решает, как что-то делать. О декларативных программах легко рассуждать, потому что сам код описывает, что он делает.

Вот пример, когда каждый элемент массива умножается на2, мы используем декларативныйmapфункцию, и пусть компилятор сделает все остальное, тогда как с императивом вам нужно написать все шаги процесса.

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

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

console.log(doubleWithDec)

// 命令式
const doubleWithImp = [];
for(let i=0; i<numbers.length; i++) {
    const numberdouble = numbers[i] * 2;
    doubleWithImp.push(numberdouble)
}

console.log(doubleWithImp)

Что такое функциональное программирование

Функциональное программирование является частью декларативного программирования. Функции в javascript являются гражданами первого класса, что означает, что функции являются данными, и вы можете сохранять, извлекать и передавать эти функции в свое приложение так же, как переменные.

В функциональном программировании есть несколько основных концепций, а именно:

  • неизменность
  • Чистые функции
  • Преобразования данных
  • Функции высшего порядка
  • рекурсия
  • комбинация

неизменность

Неизменный значит неизменный. В функциональном программировании вы не можете изменить данные и не можете изменить их. Если данные должны быть изменены или изменены, необходимо сделать копию данных для их изменения.

Например, этоstudentобъект иchangeNameФункция, если вы хотите изменить имя учащегося, вам нужно сначала скопировать объект «ученик», а затем вернуть новый объект.

В javascript параметры функции являются ссылками на фактические данные, вы не должны использовать  студент.firstName="testing11", что меняет фактическоеstudentобъект, который следует использоватьObject.assignСкопируйте объект и верните новый объект.

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);

чистая функция

Чистая функция — это функция, которая всегда принимает один или несколько аргументов, вычисляет аргументы и возвращает данные или функцию. Он не имеет побочных эффектов, таких как установка глобального состояния, изменение состояния приложения, он всегда обрабатывает параметры как неизменяемые данные.

я хочу использоватьappendAddressфункционировать, чтобыstudentОбъект добавляет адрес. Если вы используете нечистую функцию, у нее нет параметров, измените ее напрямуюstudentобъект для изменения глобального состояния.

Используйте чистую функцию, которая принимает параметры, выполняет вычисления на основе параметров и возвращает новый объект без изменения параметров.

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

// 非纯函数
function appendAddress() {
    student.address = {streetNumber:"0000", streetName: "first", city:"somecity"};
}

console.log(appendAddress());

// 纯函数
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);

конверсия данных

Мы много говорили о неизменности, о том, как мы можем изменить данные, если они неизменны. Как упоминалось выше, мы всегда генерируем преобразованные копии исходных данных вместо того, чтобы напрямую изменять исходные данные.

Еще несколько встроенных функций javascript и, конечно же, многие другие, вот несколько примеров. Все эти функции не изменяют существующие данные, а возвращают новые массивы или объекты.

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' ]

Функции высшего порядка

Функции высшего порядка — это функции, которые принимают функции в качестве аргументов или возвращают функции, а иногда и то, и другое. Эти функции более высокого порядка могут манипулировать другими функциями.

Array.map,Array.filter和Array.reduceявляются функциями высшего порядка, потому что они принимают функции в качестве аргументов.

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

Ниже приведен еще один названныйisPersonOldПример функции высшего порядка, которая принимает две другие функции, а именноmessageа такжеisYoung.

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

рекурсия

Рекурсия — это метод, при котором функция вызывает сама себя до тех пор, пока не будет выполнено определенное условие. По возможности лучше использовать рекурсию, а не цикл. Вы должны быть осторожны с этим, браузеры не могут обрабатывать много рекурсии и выдавать ошибки.

Ниже приведен пример, демонстрирующий рекурсию, где печатается имя, похожее на лестницу. Мы также можем использоватьforциклы, но по возможности мы предпочитаем рекурсию.

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<name.length; i++) {
    output = output + name[i];
    console.log(output);
}

комбинация

В React мы разделяем функциональность на небольшие повторно используемые чистые функции, и нам нужно собрать все эти многократно используемые функции вместе, чтобы в конечном итоге сделать их продуктом. Объединив все более мелкие функции в более крупную, в итоге вы получите приложение, которое называетсякомбинация.

Существует множество различных способов реализации композиции. Обычный метод, который мы знаем из Javascript, — это цепочка. ссылка используетсяточкаПредставляет метод вызова функции, которая возвращает значение предыдущей функции.

Вот пример. у нас естьname,еслиfirstNameа такжеlastNameЗаглавные буквы больше 5 слов, просто вернитесь и напечатайте имя и длину имени.

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 мы используем другой подход, чем цепочка, потому что если таких функций 30, цепочка сложна. Цель здесь состоит в том, чтобы объединить все более простые функции для получения функции более высокого порядка.

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

console.log(name);

что такое Реакт

React — это простая библиотека пользовательского интерфейса javascript для создания эффективных и быстрых пользовательских интерфейсов. Это легкая библиотека, поэтому она популярна. Он следует шаблону проектирования компонентов, парадигме декларативного программирования и концепциям функционального программирования, чтобы сделать интерфейсные приложения более эффективными. Он использует виртуальный DOM для эффективного управления DOM. Он следует за однонаправленным потоком данных от компонентов более высокого порядка к компонентам более низкого порядка.

Чем React отличается от Angular?

Angular — это полноценная среда MVC со множеством специфических функций, таких как службы, директивы, шаблоны, модули, синтаксические анализаторы и многое другое. React — очень легкая библиотека, которая фокусируется только на части представления MVC.

Angular следует за потоком данных в обоих направлениях, а React следует за однонаправленным потоком данных сверху вниз. React дает разработчикам большую свободу при разработке функций, например, как вызывать API, маршрутизировать и т. д. Нам не нужно включать библиотеку маршрутизатора, если она нам не нужна в нашем проекте.

Что такое виртуальный DOM и как он работает

React использует виртуальный DOM для обновления реального DOM, повышая эффективность и скорость. Давайте обсудим это подробно.

Что такое виртуальный DOM

Браузеры следуют инструкциям HTML для создания объектной модели документа (DOM). Когда браузер загружает HTML и отображает пользовательский интерфейс, все элементы HTML-документа становятся элементами DOM.

DOM — это иерархия элементов, начиная с корневого элемента. Например, взгляните на HTML ниже.

<div>
    <div>
        <h1>This is heading</h1>
        <p>this is paragraph</p>
        <div>
            <p>This is just a paragraon</p>
        </div>
    </div>
    <div>
        <h1>This is heading</h1>
        <p>this is paragraph</p>
        <div>
            <p>This is just a paragraon</p>
        </div>
    </div>
    <div>
        <h1>This is heading</h1>
        <p>this is paragraph</p>
        <div>
            <p>This is just a paragraon</p>
        </div>
    </div>
</div>

Когда этот HTML-код загружается в браузер, все эти элементы HTML преобразуются в элементы DOM, как показано ниже.

Когда дело доходит до приложений SPA, сначала загрузитеindex.html, И вindex.htmlЗагрузите обновленные данные в себя или в другой html. Когда пользователь просматривает сайт, мы обновляем тот же index.html новым содержимым. Каждый раз, когда DOM изменяется, браузеру необходимо пересчитывать CSS, выполнять разметку и перекрашивать веб-страницу.

React использует Virtual DOM для эффективной перестройки DOM. Это значительно облегчает нам очень сложную и трудоемкую задачу манипулирования DOM. React абстрагирует все это от разработчика, чтобы создавать эффективные пользовательские интерфейсы с помощью Virtual DOM.

Как работает виртуальный DOM

Виртуальный DOM — это не что иное, как объектное представление javascript реального DOM. Обновление объектов javascript проще и быстрее, чем обновление реального DOM. Имея это в виду, давайте посмотрим, как это работает.

React сохраняет всю копию DOM как виртуальный DOM

Всякий раз, когда происходит обновление, он поддерживает две виртуальные модели DOM для сравнения предыдущего состояния с текущим состоянием и определения того, какие объекты были изменены. Например, текст абзаца изменится на Изменить.

Теперь он сравнивает два различия виртуальных DOM и обновляет эти изменения до фактического DOM.

Как только реальный DOM будет обновлен, он также обновит пользовательский интерфейс.

Что такое JSX

JSX — это расширение синтаксиса для javascript. Это как язык шаблонов со всей мощью javascript. Он генерирует элементы React, которые будут отображаться в DOM. React рекомендует использовать JSX для компонентов. В JSX мы объединяем javascript и HTML и генерируем элементы реакции, которые можно отображать в DOM.

Ниже приведен пример JSX. Мы можем увидеть, как объединить javascript и HTML. Если HTML содержит какие-либо динамические переменные, мы должны использовать выражение{}.

import React from 'react';

export const Header = () => {

    const heading = 'TODO App'

    return(
        <div style={{backgroundColor:'orange'}}>
            <h1>{heading}</h1>
        </div>
    )
}

Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.

Компоненты и различные типы

Все в React является компонентом. Обычно мы разбиваем всю логику приложения на небольшие отдельные части. Каждую отдельную часть мы называем компонентом. Как правило, компонент представляет собой функцию javascript, которая принимает входные данные, обрабатывает их и возвращает элемент React, отображаемый в пользовательском интерфейсе.

В React есть разные типы компонентов. Давайте посмотрим поближе.

Функции/компоненты без сохранения состояния/представления

Функция или компонент без состояния — это чистая функция, которая принимает аргументы и возвращает элемент реакции. Это чистые функции без каких-либо побочных эффектов. У этих компонентов нет методов состояния или жизненного цикла, вот пример.

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

export const Header = () => {
    return(
        <Jumbotron style={{backgroundColor:'orange'}}>
            <h1>TODO App</h1>
        </Jumbotron>
    )
}

Классы/компоненты с отслеживанием состояния

Классы или компоненты с состоянием имеют состояние, и стороны жизненного цикла могут проходитьsetState()метод изменения состояния компонента. Компоненты класса создаются путем расширения React. Он инициализируется в конструкторе и также может иметь дочерние компоненты, вот пример.

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 (
      <div className="dashboard"> 
          <ToDoForm />
          <ToDolist />
      </div>
    );
  }
}

Управляемые компоненты

Управляемые компоненты — это метод обработки форм ввода в React. Элементы формы обычно поддерживают свое собственное состояние, в то время как React поддерживает состояние в свойстве состояния компонента. Мы можем объединить их для управления формой ввода. Это называется контролируемым компонентом. Таким образом, в форме контролируемого компонента данные обрабатываются компонентом React.

Вот пример. Когда пользователь вводит имя в элемент списка задач, вызовите функцию javascript.handleChangeЗахватите все входные данные и поместите их в состояние, чтобы вhandleSubmitданные об использовании в формате .

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 (
          <div className="todoform">
            <Form>
                <Form.Group as={Row} controlId="formHorizontalEmail">
                    <Form.Label column sm={2}>
                    <span className="item">Item</span>
                    </Form.Label>
                    <Col sm={5}>
                        <Form.Control type="text" placeholder="Todo Item" />
                    </Col>
                    <Col sm={5}>
                        <Button variant="primary" type="submit">Add</Button>
                    </Col>
                </Form.Group>
            </Form>
         </div>
      );
    }
  }

неконтролируемые компоненты

В большинстве случаев рекомендуются контролируемые компоненты. Существует метод, называемый неконтролируемыми компонентами, который можно реализовать с помощьюRefдля обработки данных формы. В неконтролируемом компонентеRefдля прямого отDOMДоступ к значениям формы, а не к обработчикам событий.

Мы используемRefСоздал ту же форму вместо использования состояния React. Мы используем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 (
          <div className="todoform">
            <Form>
                <Form.Group as={Row} controlId="formHorizontalEmail">
                    <Form.Label column sm={2}>
                    <span className="item">Item</span>
                    </Form.Label>
                    <Col sm={5}>
                        <Form.Control type="text" placeholder="Todo Item" ref={this.input}/>
                    </Col>
                    <Col sm={5}>
                        <Button variant="primary" onClick={this.handleSubmit} type="submit">Add</Button>
                    </Col>
                </Form.Group>
            </Form>
         </div>
      );
    }
  }

компонент контейнера

Компоненты-контейнеры — это компоненты, которые обрабатывают получение данных, подписку на хранилище избыточности и т. д. Они содержат компоненты презентации и другие компоненты-контейнеры, но никогда не содержат html внутри.

компоненты более высокого порядка

Компонент более высокого порядка — это компонент, который принимает компонент в качестве параметра и создает другой компонент. Редуксconnectявляется примером компонента более высокого порядка. Это мощная техника для создания повторно используемых компонентов.

Реквизит и состояния

Props— это свойство, доступное только для чтения, которое передается компоненту для отображения пользовательского интерфейса и состояния, и мы можем изменять выходные данные компонента с течением времени.

Ниже приведен пример компонента класса, который определен в конструктореpropsа такжеstate, всякий раз, когда используетсяthis.setState()Когда состояние будет изменено, оно будет вызвано сноваrender( )функция для изменения вывода компонента в пользовательском интерфейсе.

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 (
      <div className="dashboard"> 
          {name}
          {address}
      </div>
    );
  }
}

Что такое PropTypes

Приложения со временем становятся больше, поэтому проверка типов очень важна.PropTypesОбеспечивает проверку типов для компонентов и хорошую документацию для других разработчиков. Если проект реакции не использует Typescript, рекомендуется добавитьPropTypes.

Мы также можем определить реквизиты по умолчанию для отображения для каждого компонента, если компонент не получает никаких реквизитов. Вот пример.UserDisplayЕсть три реквизита:name,addressа такжеage, мы определяем реквизиты по умолчанию и типы реквизитов для них.

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 (
        <>
            <div>
                <div class="label">Name:</div>
                <div>{name}</div>
            </div>
            <div>
                <div class="label">Address:</div>
                <div>{address}</div>
            </div>
            <div>
                <div class="label">Age:</div>
                <div>{age}</div>
            </div>
        </>
    )
}

UserDisplay.propTypes = {
    name: PropTypes.string.isRequired,
    address: PropTypes.objectOf(PropTypes.string),
    age: PropTypes.number.isRequired
}

Как обновить статус и как не обновлять

Вы не должны изменять состояние напрямую. Значения состояния можно определить в конструкторе. Использование состояния напрямую не приведет к повторному рендерингу. Реагировать используетthis.setState()объединенное состояние.

//  错误方式
this.state.name = "some name"
//  正确方式
this.setState({name:"some name"})

использоватьthis.setState()Вторая форма всегда безопаснее, потому что обновляемые реквизиты и состояние асинхронны. Здесь мы обновляем состояние на основе этих реквизитов.

// 错误方式
this.setState({
    timesVisited: this.state.timesVisited + this.props.count
})
// 正确方式
this.setState((state, props) => {
    timesVisited: state.timesVisited + props.count
});

Методы жизненного цикла компонентов

Компоненты проходят ряд методов жизненного цикла, когда они входят в DOM и покидают его. Ниже приведены методы жизненного цикла.

componentWillMount()

Вызывается перед рендерингом, как на стороне клиента, так и на стороне сервера, это происходит только один раз.

componentDidMount()

Вызывается после первого рендера, только на стороне клиента. После того, как компонент сгенерировал соответствующую структуру DOM, вы можете передатьthis.getDOMNode()посетить. Если вы хотите использовать его с другими средами JavaScript, вы можете вызвать этот методsetTimeout, setIntervalИли отправлять операции, такие как запросы AJAX (чтобы предотвратить блокировку пользовательского интерфейса внешними операциями).

componentWillReceiveProps()

Вызывается, когда компонент получает новую опору (после обновления). Этот метод не будет вызываться при инициализации рендера.

shouldComponentUpdate()

Возвращает логическое значение. Компонент получает новыйpropsилиstateкогда звонили. при инициализации или использованииforceUpdateне называется. Может использоваться, когда вы уверены, что вам не нужно обновлять компоненты.

componentWillUpdate()

Компонент получает новыеpropsилиstateно еще нетrenderкогда звонили. Не вызывается во время инициализации.

componentDidUpdate()

Вызывается сразу после завершения обновления компонента. Не вызывается во время инициализации.

componentWillUnMount()

Вызывается немедленно, когда компонент удаляется из DOM.

getDerivedStateFromError()

Этот метод жизненного цикла находится вErrorBoundaryиспользуется в классе. Фактически, если используется этот метод жизненного цикла, любой класс становитсяErrorBoundary. Это используется для отображения резервного пользовательского интерфейса, когда в дереве компонентов есть ошибка, а не для отображения какой-то странной ошибки на экране.

componentDidCatch()

Этот метод жизненного цикла используется в классе ErrorBoundary. Фактически любой класс станет ErrorBoundary, если будет использоваться этот метод жизненного цикла. Это используется для регистрации ошибок, когда они происходят в дереве компонентов.

Комбинация вне наследства

В React мы всегда используем композицию вместо наследования. Мы уже обсуждали, что такое композиция в разделе функционального программирования. Это метод объединения простых многократно используемых функций для создания компонентов более высокого порядка. Ниже приведен пример композиции, в которой мы используем два виджета в компоненте панели инструментов.todoFormа такжеtodoList.

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

export class Dashboard extends React.Component {

  render() {
    return (
      <div className="dashboard"> 
          <ToDoForm />
          <ToDolist />
      </div>
    );
  }
}

Как применять стили в React

Есть три способа применить стили к компонентам React.

внешняя таблица стилей

В этом методе вы можете импортировать внешнюю таблицу стилей в класс, использующий компонент. Но вы должны использоватьclassNameвместоclassЧтобы применить стили к элементам React, вот пример.

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 (
    <div className="App">
      <Header />
      <Dashboard />
      <UserDisplay />
      <Footer />
    </div>
  );
}

export default App;

встроенный стиль

В этом методе мы можем напрямуюpropsПереданный элементу HTML, атрибутstyle. Вот пример. Здесь важно отметить, что мы передаем объект javascript в стиль, поэтому мы используемbackgroundColorвместо метода CSSbackbackground -color.

import React from 'react';

export const Header = () => {

    const heading = 'TODO App'

    return(
        <div style={{backgroundColor:'orange'}}>
            <h1>{heading}</h1>
        </div>
    )
}

определить объект стиля и использовать его

потому что мы передаем объект javascript вstyleсвойство, поэтому мы можем определитьstyleобъект и использовать его. Ниже приведен пример, вы также можете использовать этот объект какpropsпередается в дерево компонентов.

import React from 'react';

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

export const Footer = () => {
    return(
        <div style={footerStyle}>
            All Rights Reserved 2019
        </div>
    )
}

Что такое Redux и как он работает

Redux — это библиотека управления состоянием для React, основанная на Flux. Redux упрощает односторонний поток данных в React. Redux полностью абстрагирует управление состоянием от React.

как это работает

В React компоненты подключены к избыточности, если вы хотите получить доступ к избыточности, вам нужно отправить содержащийidи полезная нагрузкаaction. В боюpayloadявляется необязательным, действие перенаправляет его в редюсер.

когдаreducerполучатьactionкогда черезswithc...caseСравнение синтаксисаactionсерединаtype. При сопоставлении обновите соответствующий контент и верните новыйstate.

когдаReduxКогда состояние изменится, подключитесь кReduxКомпонент получит новое состояние какprops. Когда компонент получает этиprops, он войдет в фазу обновления и повторно отобразит пользовательский интерфейс.

Детали цикла Redux

Давайте подробно рассмотрим весь цикл редукции.

Action: Действие — это просто объект json,typeИ тамpayloadкак ключ.typeэто должно быть,payloadявляется необязательным. Ниже приведен пример действия.

// action

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

Action Creators: они созданыActionsфункция , поэтому мы отправляемactionбез необходимости вручную писать каждый в компонентеaction. Ниже приведен пример создателя действия.

// action creator

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

Reducers: Редюсеры — это чистые функции, которыеactionи текущийstateВ качестве аргументов вычислите необходимую логику и верните новыйstate. Эти редьюсеры не имеют побочных эффектов. это не изменится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Связь

mapStateToProps: эта функция будетstateсопоставить сprops, так что покаstateизменяется, новое состояние переназначается наprops. это подпискаstoreПуть.

mapDispatchToProps: эта функция используется дляaction creatorsПривязать к вамprops. то что мы можем12Использовать этот .props.actions.sendemail()отправить действие.

connectа такжеbindActionCreatorsиз редукса. Первый используется для подключения магазина, как в строке 22, второй используется для привязки создателей действий к вашему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это библиотека для маршрутизации в приложении. В библиотеке React нет функции маршрутизации, и ее необходимо устанавливать отдельно.react-router-dom.

react-router-dom предоставляет два маршрутизатораBrowserRouterа такжеHashRoauter. Первый основан на сегменте имени пути URL-адреса, а второй основан на сегменте хеша.

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

 后者:http://127.0.0.1:3000/#/article/num1(不一定是这样,但#是少不了的)

компонент react-router-dom

  • BrowserRouterа такжеHashRouterэто роутер.
  • RouteИспользуется для сопоставления маршрутов.
  • LinkКомпоненты используются для создания ссылок в приложениях. Он будет отображаться как тег привязки в HTML.
  • NavLinkэто специальная ссылка, которая выделяет текущую активную ссылку.
  • SwitchНе требуется, но полезно при объединении маршрутов.
  • RedirectИспользуется для принудительного перенаправления маршрута

Ниже приведен компонентLink,NavLinkа такжеRedirectпример

// normal link
<Link to="/gotoA">Home</Link>

// link which highlights currentlu active route with the given class name
<NavLink to="/gotoB" activeClassName="active">
  React
</NavLink>

// you can redirect to this url
<Redirect to="/gotoC" />

Ниже приведен пример компонента React Router. Если вы посмотрите на пример ниже, мы сопоставим путь и используемSwitchа такжеRouteОтрисовывает соответствующий компонент.

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(
        <div className="">
            <Switch>
                <Route exact path={`${match.path}/gotoA`} component={ComponentA} />
                <Route path={`${match.path}/gotoB`} component={ComponentB} />
                <Route path={`${match.path}/gotoC`} component={ComponentC} />
                <Route path={`${match.path}/gotoD`} component={ComponentD} />
                <Route path={`${match.path}/gotoE`} component={ComponentE} />
            </Switch>
        </div>
    )}

export default Layout

что такое граница ошибки

В React у нас обычно есть дерево компонентов. Если ошибка возникает в каком-либо одном компоненте, она уничтожит все дерево компонентов. Нет никакого способа поймать эти ошибки, мы можем изящно обработать их с помощью границ ошибок.

Границы ошибок служат двум целям

  • При возникновении ошибки показать резервный пользовательский интерфейс
  • ошибка журнала

НижеErrorBoundaryПример класса. Если класс реализуетgetDerivedStateFromErrorилиcomponentDidCatchлюбой из этих двух методов жизненного цикла, тогда класс становитсяErrorBoundary. бывший возвращается{hasError: true}для отображения резервного пользовательского интерфейса, который используется для регистрации ошибок.

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 <h1>OOPS!. WE ARE LOOKING INTO IT.</h1>;
      }
  
      return this.props.children; 
    }
  }

Вот как мы можем использовать ErrorBoundary в одном из наших компонентов. Оберните его классом ErrorBoundaryToDoFormа такжеToDoList. Если в этих компонентах возникает какая-либо ошибка, мы регистрируем ошибку и отображаем резервный пользовательский интерфейс.

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 (
      <div className="dashboard"> 
        <ErrorBoundary>
          <ToDoForm />
          <ToDolist />
        </ErrorBoundary>
      </div>
    );
  }
}

Что такое фрагменты

В React нам нужно иметь родительский элемент при возврате элемента React из компонента. Иногда добавление дополнительных узлов в DOM может раздражать. использоватьFragments, нам не нужно добавлять дополнительные узлы в DOM. нам просто нужно использоватьReact.Fragmentили сокращенно<>Просто заверните содержимое. Следующим образом:

 // Without Fragments   
return (
    <div>
       <CompoentA />
       <CompoentB />
       <CompoentC />
    </div>
)

// With Fragments   
  return (
    <React.Fragment>
       <CompoentA />
       <CompoentB />
       <CompoentC />
    </React.Fragment>
  )

  // shorthand notation Fragments   
  return (
    <>
       <CompoentA />
       <CompoentB />
       <CompoentC />
    </>
  )

Что такое порталы

По умолчанию все подкомпоненты представлены на UI, в зависимости от иерархии компонентов. Портал предоставляется дочерний узел для рендеринга превосходного решения, чем родительский компонент, присутствующий в узле DOM.

Вот пример. По умолчанию родительские компоненты имеют дочерние компоненты в иерархии DOM.

мы можем поставитьchildrenкомпонент удаленparentкомпонент и прикрепите егоidдляsomeidпод узлом Дом.

Сначала получаем id как someid, создаем элемент div в конструкторе и прикрепляем дочерний элемент к someRoot в componentDidMount. Наконец, мы передаем дочерний узел этому конкретному узлу DOM с помощью ReactDOM.createPortal(this.props.childen), domnode.

Сначала получите идентификатор какsomeidэлемент DOM, затем создайте элемент div в конструкторе, вcomponentDidMountлейтенант методаsomeRootв див. Наконец, поReactDOM.createPortal(this.props.childen), domnode)Будуchildrenпередается соответствующему узлу.

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,
    );
  }
}

что такое контекст

Иногда нам приходитсяpropsпередается в дерево компонентов, даже если все промежуточные компоненты не нуждаются в нихprops. контекст - это передачаpropsметод без передачи дерева компонентов на каждом уровне.

Что такое крючки

Хуки появились в React версии 16.8. Помните, что мы не можем использовать в функциональных компонентахstate, потому что они не являются компонентами класса.Хуки позволяют нам использовать состояние и другие функции в функциональных компонентах.

В настоящее время нет критических изменений, и нам не нужно отказываться от компонентов класса.

Хуки не влияют на ваше понимание концепций React. Наоборот, хуки предоставляют более прямой API для известных концепций React: свойства, состояние, контекст, ссылки и жизненные циклы. Как мы увидим позже, хуки также предоставляют более мощный способ их комбинирования.

Мы можем использовать некоторые хуки, такие как useState, useEffect, useContext, useReducer и т. д.

Вот основные правила для хуков

  • Хуки следует использовать снаружи, а не в циклах, условиях или вложенных функциях.
  • Хуки следует использовать только в функциональных компонентах.

Давайте рассмотрим пример, чтобы понять хуки. Это функциональный компонент, который принимаетpropsи отображать их в пользовательском интерфейсеprops. существуетuseStateС помощью хуков мы превращаем этот функциональный компонент в компонент с отслеживанием состояния. Во-первых, мы определяем состояние в строке 5, что эквивалентно

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

useStateвозвращает два элемента, одинuser, другойsetUserфункция.userэто то, что можно сделать безthisОбъект, используемый непосредственно в случае ключевого слова,setUserэто метод, который можно использовать для установки щелчка пользователя21Функция состояния кнопки строки, эквивалентная следующей.

this.setState({name:'name changed'})
import React, { useState } from "react";

export const UserDisplay = ({ name, address, age }) => {
    const [user, setUser] = useState({
        name: "myname",
        age: 10,
        address: "0000 onestreet"
    });

    return (
        <>
            <div>
                <div class="label">Name:</div>
                <div>{user.name}</div>
            </div>
            <div>
                <div class="label">Address:</div>
                <div>{user.address}</div>
            </div>
            <div>
                <div class="label">Age:</div>
                <div>{user.age}</div>
            </div>
            <button onClick={() => setUser({ name: "name changed" })}>
                Click me
            </button>
        </>
    );
};

Как улучшить производительность

Мы можем улучшить производительность приложения несколькими способами, важными из которых являются следующие:

  • использовать надлежащим образомshouldComponentUpdateМетоды жизненного цикла. Это позволяет избежать ненужного рендеринга дочерних компонентов. Если в дереве 100 компонентов, улучшите производительность приложения, не выполняя повторную визуализацию всего дерева компонентов.
  • использоватьcreate-react-appпостроить проект, который создает всю структуру проекта с множеством оптимизаций.
  • Неизменяемость — ключ к повышению производительности. Вместо того, чтобы вносить изменения в данные, всегда создавайте новые коллекции поверх существующих, чтобы копировать как можно меньше и, таким образом, повысить производительность.
  • Всегда использовать при отображении списка или таблицыKeys, что ускорит обновление React
  • Разделение кода — это метод вставки кода в отдельные файлы с загрузкой только тех файлов, которые требуются модулю или разделу.

Как сохранить данные при перезагрузке страницы

Одностраничные приложения загружаются первыми в DOMindex.html, а затем загружать содержимое по мере того, как пользователь просматривает страницу, или из того жеindex.htmlБэкэнд API извлекает любые данные.

Если страница перезагружается нажатием кнопки перезагрузки в браузереindex.html, все приложение React перезагрузится, и мы потеряем состояние приложения. Как сохранить состояние приложения?

Всякий раз, когда приложение перезагружается, мы используем браузерlocalstorageДля сохранения состояния приложения. Мы будем хранить данные во всемlocalstorage, всякий раз, когда происходит обновление или перезагрузка страницы, мы запускаемlocalstorageсостояние загрузки.

Как делать вызовы API в React

Мы используемredux-thunkВызов API в React. потому чтоreduceЭто чистая функция, поэтому нет побочных эффектов, таких как вызов API.

Поэтому мы должны использоватьredux-thunkСовершайте вызовы API от создателей действий. Создатель действия отправляет действие, которое помещает данные из API вpayloadсередина. Редукторы получают наши вышеreduxДанные обсуждаются в цикле, в остальном процесс такой же.

redux-thunk — это промежуточное ПО. Как только он будет введен в проект, отправляйте по одномуaction, пройдешьthunkпередача. Если это функция, она просто ждет, пока функция обработает и вернет ответ. Если это не функция, она просто обрабатывается нормально.

Вот пример.sendEmailAPIэто функция, вызываемая из компонента, который принимает данные и возвращает функцию, гдеdispatchкак параметр. Мы используемredux-thunkвызов APIapiservice, и ждите ответа. После получения ответа мы используемpayloadраспространять один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));
        });
    }
}

Суммировать

Все вышеперечисленные темы должны быть хорошо поняты, чтобы уверенно проходить собеседование. Даже если вы в настоящее время используете React, понимание этих концепций повысит вашу уверенность на рабочем месте.