Javascript, который необходимо знать для работы с Reactjs

Изучение React js не должно быть таким уж сложным, если вы уже знакомы с некоторыми концепциями Javascript. Одна из интересных вещей в использовании reactjs — это то, что он оттачивает ваши навыки работы с javascript, но прежде чем вы решите попробовать react js, убедитесь, что вы понимаете эти концепции javascript.

Одна из ошибок, которую люди допускают при изучении фреймворка/библиотеки, — это то, что он дает. Прежде чем мы начнем, вот темы, которые мы будем рассматривать. Хотя некоторые из этих тем не имеют прямого отношения к reactjs, вы, вероятно, будете часто видеть их в кодовой базе react. Обратите внимание, что большинство тем, упомянутых здесь, относятся к функциям es6 и es-next javascripts.

  • Let и Const
  • Тернары
  • Шаблонные литералы
  • Свойства сокращений
  • Восстановление/распространение
  • Деструктуризация
  • Параметры по умолчанию
  • Модули ЭП
  • Оценка короткого замыкания
  • Функции высшего порядка (методы массивов)
  • Операция нулевого коалесцирования
  • Дополнительная цепочка
  • Стрелочные функции

Введение

React js — это открытая библиотека javascript, которая позволяет нам создавать быстрые, декларативные и компонентно-ориентированные веб-разработки. С помощью react js можно создавать веб-приложения, кроссплатформенные мобильные приложения (react native), настольные приложения (electron, node gui), прогрессивные веб-приложения (pwas). Поэтому изучать react js стоит потому, что вы можете использовать свои знания для создания множества вещей.

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

<button onclick='displayData'> see users </button>
<div id='users'>
</div>
<div id='loading'>
</div>
<div id='error'>
</div>
Войти в полноэкранный режим Выход из полноэкранного режима
const usersUI = document.getElementById("users");
const loadingUI = document.getElementById("loading");
const errorUI = document.getElementById("error");
const apiUrl = "https://jsonplaceholder.typicode.com/users";

// fetch data from an api
const fetchData = async () => {
const res = await fetch(apiUrl);
return await res.json();
};

// display your data to the ui
const displayData = async () => {
errorUI.innerHTML = "";
loadingUI.innerHTML = "Loading...";

fetchData()
.then((users) => {
usersUI.innerHTML = users.map((item) => <p>$ {item.name}</p>);
})
.then(() => (loadingUI.innerHTML = ""))
.catch(() => {
loadingUI.innerHTML = "";
errorUI.innerHTML = "Error fetching data";
});
};
Войти в полноэкранный режим Выйти из полноэкранного режима
import React, {useState} from 'react'

const User = ()=>{
const [loading, setLoading] = useState=(false)
const [hasError, setHasError] = useState("")
const [users, setUser] = useState([])

const loadData = async()=>{
setLoading(true)
setHasError("")
fetch(apiUrl).then(res=> res.json() )
.then((data)=> {
setUsers(data)
})
.catch((error)=> setHasError(error))
.finally(()=>setLoading(false))
}
return (

<div>
  <button onClick={loadData}> load users </button>
  {loading ? "Loading..." : ""}
  {!!users && users.map((user) => <p> {user.name} </p>)}
  {!!hasError && "Error Fetching Data"}
</div>
) } 
Войти в полноэкранный режим Выход из полноэкранного режима

Посмотрите, как мы начинаем с нацеливания на элементы из html, создания api и установки соответствующего UI из функции, а если у нас до 100 UI для обновления на экране, то это быстро превратит код в спагетти. По сравнению с нашей версией react, мы задаем состояние нашего приложения в html-подобном синтаксисе, называемом jsx.

Let и Const

Let и const — это похожие способы объявления переменной в javascript. Ключевое слово let указывает на то, что переменная может быть переназначена на другое значение, в то время как с const мы говорим, что это окончательное значение.

let favNumber = 7;
const LargestSea ='The Philippine Sea'
Вход в полноэкранный режим Выйти из полноэкранного режима

favNumber можно переназначить без проблем, но если вы попытаетесь переназначить LargestSea, вы получите ошибку парсера, Assignment to constant variable..

Тернары

Тернары — это более короткий способ объявления оператора if-else в программировании. Например, объявление функции, проверяющей, является ли число четным;


function isEven(input){
const even = n % 2 == 0;
if(even) {
  return true
  } else    { 
    return false
   }
}
Вход в полноэкранный режим Выход из полноэкранного режима

это можно переписать в input % 2===0 ? true :false выражение input % 2===0, проверяет наличие ?, который указывает выход, если утверждение истинно, а : указывает, что поместить в выход else.
Практический пример — условное добавление className или style при выполнении операции.

 <div className={success?'success-item' :'item'}>
      Items List
  </div>
Войти в полноэкранный режим Выход из полноэкранного режима

Хотя вы можете иметь несколько вложенных тернариев, это не считается лучшей практикой, так как снижает читаемость кода.

Шаблонные литералы

Шаблонные литералы — это более чистый способ объединения элементов в выражении javascript. Он начинается с объявления обратных знаков, затем следует знак $ и фигурные скобки с предполагаемой переменной, которая будет объединена между фигурными скобками, структура выглядит так: ${переменная}другие тексты. Возьмем, например,
let age = 10; вы, вероятно, конкатенируете как,

const ageOutput = 'You are ' + age + ' years old'
Вход в полноэкранный режим Выход из полноэкранного режима

Мы можем сделать лучше, написав что-то вроде этого в шаблонных литералах, const ageOutput = `Вам ${age} лет`. Посмотрите, как это чисто. Практический пример в react, мы немного расширим наш пример с тернарным оператором, скажем, у вас также есть различные классы в div ниже, наличие «item-section first-section» рядом с фигурными скобками указывает на это как на строку, это прекрасно работает без необходимости конкатенации.

  <div className={ $ {success?'success-item' :'item'} item-section first-section}>
    Items List
  </div>
Вход в полноэкранный режим Выход из полноэкранного режима

Сокращенные свойства

Возьмем, к примеру, пример объекта,

const name = "Roy"
let user = { name:name }
Войти в полноэкранный режим Выйти из полноэкранного режима

мы можем переписать это так: let user= {name}
обратите внимание, ‘name’ теперь в единственном числе внутри объекта.

Отдых/Расширение

Rest/Spread — это функция es6 для копирования, объединения массивов в javascript. Она начинается с «…» с тремя точками, за которыми следует то, что вы хотите объединить или скопировать.

Например, если у нас есть образец данных,

Объекты

const user  = {
  name:'Tony',
  age:12
}

const otherPropertie = {
   hobby:'hiking',
   bestColor:'red'
 }
Войти в полноэкранный режим Выйти из полноэкранного режима

если мы хотим объединить это до es6, мы можем использовать метод Object.assign.

Метод Object.assign() позволяет скопировать все перечислимые собственные свойства из одного или нескольких исходных объектов в целевой объект и вернуть целевой объект, Object.assign(target, user, Obj2, Obj3, ...) :

let finalMerge = Object.assign({}, user, otherProperties)

console.log(finalMerge) // { name: 'Tony', age: 12, hobby: 'hiking', bestColor: 'red' }
Вход в полноэкранный режим Выход из полноэкранного режима

Используя оператор spread, мы можем просто выразить это так, let finalMerge = {...user, ...otherProperties}.

Массивы

Возьмем для примера два массива;

const permissions = ['view user', 'view reports', 'download reports']
const otherPermissions = ['initiate transactions', 'delete user']
Вход в полноэкранный режим Выход из полноэкранного режима

До es6 мы могли использовать метод объединения массивов, const finalArray = permissions.concat(otherPermissions) даст нам что-то вроде этого ['view user', 'view reports', 'download reports', initiate transactions', 'delete user']. Мы можем сделать лучше, используя оператор spread,

const finalMerge = [...permissions, ...otherPermissions]
Войти в полноэкранный режим Выйти из полноэкранного режима

Деструктуризация

Деструктуризация — это способ доступа к значениям внутри объекта или массива более чистым и читабельным способом.

Деструктуризация объекта

const person ={
  favNumber:'green',
  name:'Mike',
  cars:['mercedes', 'toyota']
}
Вход в полноэкранный режим Выход из полноэкранного режима

В es6, если мы хотим получить отдельные свойства объекта person, нам нужно сначала присвоить каждое из свойств переменной;

const favNumber = person.favNumber;
const name = person.name
const cars = person.cars

Вход в полноэкранный режим Выйти из полноэкранного режима

С деструктуризацией объекта мы можем сделать что-то вроде следующего;

const { favNumber, name, cars } = person
console.log(favNumber, name, cars) // green, Mike, ['mercedes', 'toyota']
Вход в полноэкранный режим Выйти из полноэкранного режима

Посмотрите, как мы можем получить значения без необходимости переназначать их. Мы все еще можем делать некоторые вещи с деструктуризацией объектов, что если мы хотим переименовать свойство name на объекте person сразу после деструктуризации, мы можем сделать что-то вроде этого.

  const {name:realName, favNumber, cars} = person,
  console.log(realName) // "Mike".
Вход в полноэкранный режим Выход из полноэкранного режима

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

const {name, favNumber, cars, favFood='jollof rice'  } = person
console.log(favFood) // 'jollof rice'
Войти в полноэкранный режим Выход из полноэкранного режима

Мы даже можем продолжить и деструктурировать вложенные объекты, например


const customer = {
name:'Tom',
mobile:"078 7070 2325",
email:tomfield@email.com,
address:{
country:'UK',
city:'East Davoch',
zipCode:AB34,
street:'33 Guildford Rd'
 } 
}
Войти в полноэкранный режим Выйти из полноэкранного режима

если мы хотим получить страну customer, мы можем деструктурировать ее,

const {address: { country } } = customer
console.log(country) // UK
Войти в полноэкранный режим Выйти из полноэкранного режима

В нашей предыдущей теме мы говорили о ‘rest/spread’, давайте поговорим об операторе rest, в большинстве случаев мы используем оба оператора как взаимозаменяемые, в частности мы используем ‘rest’ для копирования части или остальной части массива или объекта.


const {cars, favNumber, ...otherObj} = person
console.log(otherObj) // {name:'Mike'}
Вход в полноэкранный режим Выйти из полноэкранного режима

Копируется остальная часть объекта для использования. Практический пример с react


const HeaderComponent = ({title, ...restProps})=>{
return <div {...restProps}> {title} </div>
}
Вход в полноэкранный режим Выход из полноэкранного режима

мы можем использовать наш HeaderComponent следующим образом <HeaderComponent className='my-item' /> тем самым применяя наш класс ‘my-item’, как если бы мы добавили его вручную к самому компоненту.

Деструктуризация аргумента функции

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


let car = {name:'Tesla', color:'red'}

function getCar({name, color}){
 return `Your car is ${name} with the color ${color}`
}
Войти в полноэкранный режим Выйти из полноэкранного режима

В аргументе функции getCar мы можем деструктурировать его, поскольку знаем, чего ожидаем.

Деструктуризация массива

Деструктуризация массива работает аналогично деструктуризации объекта. Например, рассмотрим пример данных ниже.


const users = ['John', 'Mike', 'Cole', 'Bekky']
const [a,b, ...others] =users

console.log(a,b, others) // 'John', 'Mike', ['Cole, Bekky']
Вход в полноэкранный режим Выход из полноэкранного режима

Практическим примером в react является функция useState

import {useState} from 'react'
const [loading, setLoading] = useState(false)
Вход в полноэкранный режим Выйти из полноэкранного режима

Параметры по умолчанию

Параметры по умолчанию позволяют нам установить значение по умолчанию для параметра функции, если он отсутствует при вызове. Например;


function greetUser(username='user'){
 return `Welcome ${username}, hope you bought some pizzas`
}

const greetingsOne = greetUser('Greg')
console.log(greetingsOne) // 'Welcome Greg, hope you bought some pizzas'

const greetingsTwo = greetUser()
console.log(greetingsTwo) // 'Welcome user, hope you bought some pizzas'
Войти в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание на разницу между двумя приветствиями: во втором приветствии имя пользователя возвращается как ‘user’, потому что это то, что мы передали в качестве значения по умолчанию.

Модули ES

ES Modules — это стандартный способ работы Javascript с файлами javascript, которые передают значения, необходимые из других файлов/мест, используя ключевое слово export. Стоит отметить, что стандарт commonjs существует уже много лет, но реализация ECMAScript (стандарт JavaScript, предназначенный для обеспечения совместимости веб-страниц в различных браузерах), ES-модуль определяет способ, которым браузеры анализируют и загружают файлы javascript.

Модуль ES

person.js

export const person = {
  name:'Simon',
  color:'yellow'
}
Вход в полноэкранный режим Выход из полноэкранного режима

user.js


import { person } from 'person.js'
console.log(person) // { name:'Simon', color:'yellow' }
Вход в полноэкранный режим Выход из полноэкранного режима

Мы можем экспортировать значения в наш js файл двумя способами, named export и default export, наш первый пример в, person.js — это именованный экспорт, имя, которое вы используете для объявления его в файле, должно быть тем же именем, которое вы используете для импорта, в нашем случае, ‘person’, но что если у нас уже есть переменная в нашем файле с таким же именем? Тогда мы можем переименовать ее с помощью псевдонима import {person as currentPerson } from './person.js' мы успешно переименовали person в currentPerson.

import { person as currentPerson } from "./person.js";

console.log(currentPerson) // { name:'Simon', color:'yellow' }
Перейдите в полноэкранный режим Выход из полноэкранного режима

Экспорт по умолчанию

Экспорт по умолчанию позволяет нам представить внешнему миру только одно значение в js-файле. Он указывается с помощью ключевого слова export default 'value' обычно в нижней части файла или сразу после его объявления. Вы можете использовать экспорт по умолчанию только один раз в файле, в противном случае произойдет ошибка парсера;

colors.js

const colors = ['red', 'blue', 'green', 'orange']

export default colors;
Вход в полноэкранный режим Выйти из полноэкранного режима

views.js

import colorList from './colors.js'

console.log(colorList) // '['red', 'blue', 'green', 'orange']'
Войти в полноэкранный режим Выход из полноэкранного режима

Когда файл экспортируется по умолчанию, вы можете импортировать его с любым именем, мы могли бы назвать его ‘colorList’, ‘colorsArray’, и он все равно будет работать нормально.

Короткие замыкания

Короткое замыкание — это оценка выражения слева направо, пока не будет подтверждено, что уже оцененные условия не влияют на остальные условия, тем самым пропуская ненужные работы, что приводит к эффективной обработке. Short cicuits поддерживает два оператора, (&&) AND и (||) OR.


AND (&&)
true && 'Hello' -> This outputs 'Hello'
true && true && false -> This outputs 'false'

false && true -> This outputs 'false'
(true && false) && false -> This outputs 'false'

OR (||)

true || false -> This outputs true

false || 'hello' || false -> This outputs 'hello'
Вход в полноэкранный режим Выход из полноэкранного режима

Практическое использование реакции

import {useState, useEffect} from 'react';

const Items = ()=>{
const [loading, setLoading] = useState(false)
const [data, setData] = useState([])
async function ladData(){
const response = await (await fetch('http://apiEndPoint')).json()
setData(response)
setLoading(false)
}
useEffect(()=>{
   setLoading(true)
   loadData()
},[])

return (

<div>
  {loading && "Loading"} // while loading is true shows 'Loading...'
  {data.lengtht && data.map((item) => <p key={item.id}> {item.sampleName} </p>)}
  // if data.length is truthy, ie, it's length is greater than 1 // then go
  ahead to ahead to show list in the UI
</div>
) }
Вход в полноэкранный режим Выход из полноэкранного режима

Будьте осторожны при использовании замыкания для условного рендеринга, сценарии типа zero и undefined могут привести к странному поведению пользовательского интерфейса.
Например,

const Todos = ()=>{

const list = []
return (

<div>
  {list.length && list.map((todo) => <p key={todo.id}> 
  {todo.title} </p>)}
</div>
) }
Войти в полноэкранный режим Выйти из полноэкранного режима

Угадайте, что будет отображаться в списке дел? «0». Да, в основном javascript интерпретирует нулевое или неопределенное значение как ложное значение. Одним из способов решения этой проблемы является приведение list.length к boolean, !!list.length или Boolean(list.length) предотвратило бы такую ошибку.

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

Функции высшего порядка (ФВП) — это функции, которые принимают другую функцию в качестве аргумента/параметров или возвращают функцию.

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

  • Найти
  • Фильтр
  • Карта
  • Включает
  • Уменьшить

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


const users = [
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"lifeTimePurcahse":4000
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna@melissa.tv",
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"lifeTimePurcahse":78200

    },
    {
      "id": 3,
      "name": "Clementine Bauch",
      "username": "Samantha",
      "email": "Nathan@yesenia.net",
      "phone": "1-463-123-4447",
      "website": "ramiro.info",
      "lifeTimePurcahse":600
    },
    {
      "id": 4,
      "name": "Patricia Lebsack",
      "username": "Karianne",
      "email": "Julianne.OConner@kory.org",
      "phone": "493-170-9623 x156",
      "website": "kale.biz",
      "lifeTimePurcahse":10000
    },

]
Вход в полноэкранный режим Выйти из полноэкранного режима

Найти

Метод find принимает в качестве аргумента функцию и возвращает элемент find, удовлетворяющий функции проверки.

  function Checker(item){
return item.id === 1
}

users.find(checker) // or users.find((item)=> item.id ===1) both functions returns the same output
// {
//"id": 1, "name": "Leanne Graham", "username": "Bret","email": "Sincere@april.biz",
// "phone": "1-770-736-8031 x56442", "website": "hildegard.org","lifeTimePurcahse":4000
// }
Войти в полноэкранный режим Выйти из полноэкранного режима

Фильтр

Метод filter возвращает новый массив, заполненный элементами, которые прошли проверку, заданную функцией обратного вызова. Он не изменяет и не мутирует исходный массив.

const userPurchases = users.filter(user => user.lifeTimePurchase > 70000)
// only user with id 2 has lifetimePurchase greater than 70,000
console.log(userPurchases)
// [ {
// "id": 2,
// "name": "Ervin Howell",
// "username": "Antonette",
// "email": "Shanna@melissa.tv",
// "phone": "010-692-6593 x09125",
// "website": "anastasia.net",
// "lifeTimePurcahse":78200
// }]
Войти в полноэкранный режим Выход из полноэкранного режима

Filter всегда возвращает массив с отфильтрованными результатами.

Метод Map

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


const userIds = users.map((user, index)=> user.id)
console.log(userIds) // [1,2,3,4]
Вход в полноэкранный режим Выход из полноэкранного режима

Включает

Метод include используется для проверки наличия заданного элемента в массиве, он возвращает булево значение, либо true, либо false.

const userIsPresent = users.map(i=> i.id).includes(1)

console.log(userIsPresent) //true
Войти в полноэкранный режим Выйти из полноэкранного режима

Метод уменьшения

Метод reduce принимает функцию reducer, чтобы вернуть единственное значение,

Анатомия метода reduce выглядит следующим образом;


function reducerFunc(total, currVal, currIndex, arr){
// currIndex -> Current Index during iteration
// arr -> The whole
// total -> current total on each iteration
//currVal -> Current value on each iteration

return total + currVal.lifeTimePurchase

}
// we are setting zero as the initial value of total
const totalLifeTimePurchases = users.reduce(reducerFunc,0)

console.log(totalLifeTimePurchases) // 92800
Вход в полноэкранный режим Выход из полноэкранного режима

Давайте посмотрим на примере функции высшего порядка;

const Users =()=>{
const currenttUserId=3
const vipUserPurchase = 10000
const raffleUserWinners = [1,4,3]

// map
const _users = users.map(user => (<p key={user.id}> 
  {user.username} </p>))

 function reducerFunc(total, currVal){
    return total + currVal.lifeTimePurchase
 }

//reduce
const totalLifeTimePurchases= users.reduce(reducerFunc,0)

// find
const currentUser = users.find(user=> user.id== currentUserId)

//filter
const vipList = users.filter(user=> user.lifeTimePurchase >= vipUserPurchase)

// includes
const isRaffleWinner = users.map(user=>user.id).includes(currenttUserId)

return (
<div>
{_users}
<p>Total Purchase: {totalLifeTimePurchase} </p>
<p>current user: {currentUser.username} </p>

    <h4> vip list <h4>
    {
      vipList.map(user=> <p key={user.id}> {user.username} </p>)
    }

    raffle status: {isRaffleWinner ? 'Congrats, you're a raffle winner' : 'Oops! Try again later'}

    </div>)

}
Вход в полноэкранный режим Выход из полноэкранного режима

Нулевая коалесцирующая операция

Nullish coalescing operations(??) позволяет нам возвращать правый операнд, когда левый операнд равен null или не определен;


const a =12
const b = 50;

a ?? b // -> 12

let c;
let d =45
c ?? d // -> 45
Вход в полноэкранный режим Выход из полноэкранного режима

Необязательная цепочка

Optional chaining(?.) позволяет нам безопасно обращаться к ключу объекта или вызывать функции, когда мы не уверены, будет ли он доступен или нет.


let user = {
name: "Joe",
details: { age: 82 }

};
const userTown= user?.address?.town;
console.log(userTown); // undefined
const user.fullInfo?.() // undefined
Вход в полноэкранный режим Выход из полноэкранного режима

Функции стрелок

Стрелочные функции, также называемые толстыми стрелками, являются альтернативным способом объявления функций в яваскриптах. Они ведут себя по-разному в том, как они обрабатывают this, они привязываются к this контексту выполнения их родительского класса/объекта. но поскольку текущая конвенция в react — это хуки, а не классы es6, нам не нужно сильно беспокоиться о this. пользователь должен явно привязать this функции к родительским элементам. Они также обеспечивают короткий и неявный способ возврата значений из функции.


const sum = (a + b)=> a+b
const sqaure = (a)=> a**2
// can even be shortened to square = a =>a**2, when we have a singular argument.

// this is the same as

function sum(a,b){
   return a + b;
 }
//sum()

function square(a){
   return a**2
  }

// React Example
function List({List=[]}) {
return (

<ul>
  {list.map((item) => (
    <li key={item.id}>{item.name}</li>
  ))}
</ul>
) } 
Вход в полноэкранный режим Выход из полноэкранного режима

Заключение

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

Другие важные вещи, которые вы можете изучить, это классы ES6 и async/await.

Спасибо за прочтение, до встречи в следующей статье!


Следите за мной, чтобы узнать больше интересных статей 👇👇👇

okeken

Опытный Front End Engineer, специализирующийся на React Web Applications. Когда не работает с Javascript, любит создавать Dapps на экосистеме Ethereum.

Оцените статью
devanswers.ru
Добавить комментарий