## КРЮЧКИ + CONTEXTAPI === УДИВИТЕЛЬНО

Отказ от ответственности: только для разработчиков ReactJS/JS — TLDR

Эй НЕРТЫ. Мы собираемся обсудить некоторые ПОТРЯСАЮЩИЕ концепции в React, такие как

  • Хуки (useState, useEffect, useContext и useReducer) &
  • Контекстный API

ПЕРВОЕ,

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

С этим уточнением, давайте начнем ->
Для тех, кто какое-то время использует компоненты класса, согласно документам КРЮЧКИ являются новым дополнением в Реагировать 16.8 и к февралю 2021 года ему будет 2 года (может быть, не такой новый)

Сказав это, хуки лучше, когда речь идет о производительности, абстракции и удобочитаемости по сравнению с компонентами на основе классов. Да правда, если не веришь мне на слово, возьми с Демонстрация основной команды React
ПРИМЕЧАНИЕ. Видео посвящено вдохновению для HOOKS.

Но… Что такое ГАК?

Предоставляет некий прямой API, который заставляет нас использовать состояние в функциональных компонентах. Проще говоря, они позволяют вам использовать состояние и другие функции реагирования без необходимости писать класс.

Вот реализация хука под названием useState крючок например

import React, { Fragment, useState } from "react"; export const Example = () => { const [name, setName] = useState(""); const [login, setLogin] = useState(false); return ( <Fragment> {!login ? ( <input type="name" value={name} placeholder="Enter your Name" onChange={(e) => setName(e.target.value)} />
 ) : ( <div className="display__text">Hello {name}</div>
 )} <button type="submit" onClick={() => setLogin(!login)}> {!login ? "Login" : "Go back"} </button>
 </Fragment>
 );
};

Базовая реализация useState

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

Да, ты можешь useState столько раз, сколько вы хотите, ограничений нет, но есть одно предостережение в отношении использования хуков в целом, то есть они должны использоваться только внутри определения функции.

Просто для сравнения проверьте реализацию эквивалентного компонента класса здесь,

import React, { Component, Fragment } from "react"; export class Example extends Component { constructor(props) { super(props); this.state = { name: "", login: false }; } render() { return ( <Fragment> {!this.state.login ? ( <input type="name" value={this.state.name} placeholder="Enter your Name" onChange={(e) => this.setState({ name: e.target.value })} />
 ) : ( <div className="display__text">Hello {this.state.name}</div>
 )} <button type="submit" onClick={() => this.setState({ login: !this.state.login })} > {!this.state.login ? "Login" : "Go back"} </button>
 </Fragment>
 ); }
}

Реализация на основе классов

Бьюсь об заклад, вы уже видите разницу, не только удалены 10 ненужных строк, общая логика кода выглядит аккуратно. Мы можем углубиться в реализацию наших хуков.

import React, { Fragment, useState } from "react"; export const Example = () => { //using objects to keep multiple states const [state, setState] = useState({ name: "", login: false }); const { name, login } = state; return ( <Fragment> {!login ? ( <input type="name" value={name} placeholder="Enter your Name" onChange={(e) => setState({ ...state, name: e.target.value })} />
 ) : ( <div className="display__text">Hello {name}</div>
 )} <button type="submit" onClick={() => setState({ ...state, login: !login })} > {!login ? "Login" : "Go back"} </button>
 </Fragment>
 );
};

Модифицированная реализация useState

Ну, это выглядит лучше, чем раньше. Вместо использования многих useState(s) , независимо от количества состояний в вашем приложении, мы можем использовать одно useState вызов с объектом для учета всех состояний. Кроме того, проверьте, что я также изменил setLogin, setName на один вызов setState с помощью (...) спред оператор для обновления соответствующих состояний по конкретному событию.

Все в порядке. Но как использовать такие методы жизненного цикла, как componentDidMount, componentDidUpdate, componentWillUnmountдля вызовов API или побочных эффектов в HOOKS?

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

import React, { Fragment, useState, useEffect } from "react";
import Axios from "axios"; export const Example = () => { const [state, setState] = useState({ posts: [] }); const postsUrl = " useEffect(() => { //Fetching Posts const fetchPosts = async () => { const posts = await Axios.get(postsUrl); setState({ ...state, posts: posts.data }); }; try { fetchPosts(); } catch (err) { console.log("Network error", err); } //dependency array is none, it acts as componentDidMount }, []); return ( <> <h1>My posts</h1>
 <ul> {state.posts.length > 0 && state.posts.map((posts, index) => { return <li key={index}>{posts.title}</li>;
 })} </ul>
 </>
 );
};

Базовая реализация useEffect (componentDidMount)

import React, { useState, useEffect } from "react"; export const Example = () => { const [title, setTitle] = useState(""); useEffect(() => { document.title = title; //runs everytime when title state is changed //Acts as componentDidUpdate }, ## HOOKS + CONTEXTAPI === AWESOME); return ( <input type="text" name="title" value={title} placeholder="Enter your title" onChange={(e) => setTitle(e.target.value)} />
 );
};

Базовая реализация useEffect (componentDidUpdate)

Сверху вы можете видеть componentDidMount & componentDidUpdate реализация в хуках с useEffect. Первый извлекает сообщения из поддельной конечной точки API rest, а пустой массив зависимостей передается в качестве второго аргумента для имитации. componentDidMount а второй обновляет вкладку заголовка браузера всякий раз, когда значение поля ввода обновляется пользователем. Обратите внимание, что он имеет значение массива зависимостей и имитирует componentDidUpdate.

В дополнение к useState & useEffect крючок есть встроенные_в_хуки вроде useReducer, useRef, useLayoutEffect и еще кое-что, что вы можете проверить Реагировать Документы

Хорошо! Что такое контекст в двух словах?

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

import React, { createContext } from "react"; //creating context
export const AppContext = createContext(); //Not necessary in react new versions
export const AppConsumer = AppContext.Consumer; //Exporting provider
export const AppProvider = ({ children }) => { return <AppContext.Provider>{children}</AppContext.Provider>;
};

useReducer С контекстным API (AppContext.js)

Вы можете видеть, я должен createcontext сначала и передавать ему начальные значения необязательно, затем экспортировать соответствующие context а также provider в AppContext.js.

Примечание. Вы должны обернуть children опора внутри Provider
передать значения, которые вы хотите передать value подпирать Provider так что вы можете использовать последние значения везде, где вы хотите использовать в дереве компонентов (здесь мы передали функцию отправки и состояние)

import React from "react";
import "./styles.css";
import { Example } from "./Components/Example";
import { AppProvider } from "./Contexts/AppContext"; export default function App() { return ( <AppProvider> <Example /> </AppProvider>
 );
}

useReducer С контекстным API (App.js)

Обязательно оберните провайдера компонентами, в которых вы хотите использовать значения контекста. App.js также.

Итак, все готово, прежде чем говорить о том, как использовать значения контекста внутри соответствующих компонентов, есть еще один хук, который нам нужно обсудить, который имитирует то, как redux работы называются useReducer

Альтернативный текст

Для тех, кто не знает, как redux работает, это простая блок-схема, которая хорошо объясняет

Redux довольно сложно понять, но, говоря простым языком, мы, как пользователи, отправляем действие (инициируем событие) в приложении, есть чистая функция, называемая reducerкоторый выполняет соответствующее действие и текущее состояние, обновляется новым состоянием на основе действия.

import React, { createContext, useReducer } from "react";
//importing Reducer
import { reducer } from "../reducer"; //creating context
export const AppContext = createContext(); //Not necessary in react new versions
export const AppConsumer = AppContext.Consumer; //Exporting provider
export const AppProvider = ({ children }) => { //usng useReducer hook and passing reducer and initial state to it const [state, dispatch] = useReducer(reducer, []); //pass the app state and dispatch function to the value prop in provider return ( <AppContext.Provider value={{ state, dispatch }}> {children} </AppContext.Provider>
 );
};

useReducer С контекстным API (AppContext.js)

useReducer ловушка принимает две вещи — функцию редуктора и состояние и снова возвращает две вещи: состояние и функцию отправки.

//reducer function which takes in dispatched action and update
//the respective state export const reducer = (todos, action) => { switch (action.type) { case "ADD_TODO": return [...todos, { id: Date.now(), todoName: action.payload.todoName, completed: false }]; default: return todos; }
};

useReducer WITH contextAPI (reducer.js)

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

Итак, todos — это наше начальное состояние, и с помощью редьюсера мы обновляем состояние, здесь оно добавляется в массив todo с условием типа действия и полезной нагрузки.

Все хорошо. Теперь остается только один элемент, чтобы решить эту головоломку, а именно добавление функции диспетчеризации для отправки формы. Для этого, если ты помнишь, мы прошли state а также dispatch в Provider . Чтобы получить к нему доступ, у нас есть еще один хук, который называется useContextкоторый принимает параметр соответствующего провайдера. Просто используя эту одну строку, мы получим доступ к значениям контекста.

import React, { Fragment, useState, useContext } from "react";
import { AppContext } from "../Contexts/AppContext";
import { Todo } from "./Todo"; export const Example = () => { const [todoName, setTodoName] = useState(""); // here used useContext hook to access state & dispatch from top level const { state, dispatch } = useContext(AppContext); const handleSubmit = (e) => { e.preventDefault(); //dispatching action here along with payload dispatch({ type: "ADD_TODO", payload: { todoName: todoName } }); setTodoName(""); }; return ( <Fragment> <form onSubmit={handleSubmit}> <input type="text" name="todoName" value={todoName} onChange={(e) => setTodoName(e.target.value)} placeholder="Enter the todo Name" /> <button type="submit">Submit</button>
 <Todo todos={state} />
 </form>
 </Fragment>
 );
};

useReducer WITH contextAPI (Example.js)

Теперь, когда у нас есть отправка, мы хотим прикрепить ее к отправке формы и передать вместе с ней тип действия и полезную нагрузку.

Наконец, передайте состояние, которое вы получаете от useContext, в Todo Component, чтобы перечислить его под полем.

Это может привести к одному вопросу, почему так много кода только для обновления состояния, я могу легко сделать это с помощью useState. Да, ты можешь. Но что, если вы хотите обновить задачу, удалить задачу, пометить как выполненную, тогда будет много сложностей, если вы используете useStateвот где useReducer пригодится.

useReducer ПРОТИВ useState
useReducer предназначен для обработки сложных обновлений состояния, каждое действие для приложения будет упоминаться только в функции редуктора, которая делает изменения состояния предсказуемыми. Хотя оба делают одно и то же, использование одного над другим полностью зависит от ситуации, в которой вы находитесь.

Последние мысли:

Это не ВСЕ, есть и другие хуки, которые имеют хорошие варианты использования, но здесь они не рассматриваются. Оформите заказ, если вы хотите узнать больше о HOOKS в этом документы. Как только вы почувствуете себя уверенно в использовании хуков, вы сможете научиться разрабатывать свои собственные ПОЛЬЗОВАТЕЛЬСКИЕ КРЮЧКИ. * Да, вы можете это сделать.

Пожалуйста, дайте мне знать, если я что-то пропустил,

Счастливого кодирования*

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *