[Разработка веб-сайтов, JavaScript, API, ReactJS] Соединяем Redux и GraphQL на простом примере
    
    
        
    
    
    
    
            
    
        
            
                
                                    
                
                                    
                
                    
                
            
        
    
    
        
            
                
                
                    
                         
                         
                       
                    
                        Автор 
                        Сообщение 
                    
                                        
                        
                            
                                
                                
                                                                                                            news_bot ®
                                                                        
                                                                                                                                                
                                                                            
                                                                                                                
                                            Стаж: 7 лет 8 месяцев                                        
                                                                                                                
                                            Сообщений: 27286                                        
                                                                                                                                                
                                                             
                            
                                
                             
                         
                        
                            
                                
                                    
                                        
                                        
 
Попробуем соединить Redux и GraphQL без использования Apollo Client или Relay.Что такое ReduxРедакс это архитектурный подход, который реализован в виде небольшой библиотеки. Он предполагает, что у приложения есть хранилище данных state. Изменять хранилище state напрямую нельзя. Это можно сделать только через вспомогательные функции reducers. Псевдокод:
function dispatch(action) {
    state = reducer(state, action);
}
Для соединения реакта и редакса используется библиотека react-redux. Она позволяет получать данные из state внутри компонентов и инициировать их обновление через dispatch.Что такое GraphQLGraphQL для клиента это просто POST-запрос с особым форматом body:RESTGraphQLGET /books/idPOST /graphql
query{ book(id) {} }POST /books
{…}POST /graphql
mutation{ addBook() {...} }UPDATE /books/id
{…}POST /graphql
mutation{ updateBook(id) {...} }DELETE /books/idPOST /graphql
mutation{ deleteBook(id) {} }GraphQL без Apollo Client (и Relay)Apollo-client это самая популярная библиотека для работы с GraphQL. Она предоставляет интерфейс для работы с запросами внутри компонентов, а также решает задачу хранения кэша. Вместо Redux предполагается использовать внутренние механизмы. Однако эти механизмы далеко не такие простые и удобные.Вместо Apollo Client для примера воспользуемся такой функцией:
const graphqlAPI = (query, variables) => fetch("/graphql", {
    method: "POST",
    body: JSON.stringify({ query, variables })
});
redux-toolkitЯ буду использовать официальный набор утилит от redux — redux-toolkit. Они решают самую частую претензию к редаксу — бесконечное количество шаблонного кода. В этот набор входит:
- createEntityAdapter для упрощения работы с редьюсерами и селекторами.
 
- createAsyncThunk для упрощения работы с сайд-эффектами и API.
 
- createSlice для упрощения работы с actions и разрешения мутабельности.
 
ПримерПредставим простое приложение, которое запрашивает список книг с сервера и выводит их.
// booksSlice.js
import {
  createEntityAdapter,
  createAsyncThunk,
  createSlice
} from "@reduxjs/toolkit";
// Наш редьюсер будет хранить список книг.
// createEntityAdapter генерирует готовый набор функций
// для добавления, обновления и удаления книг внутри редьюсера
// (addOne, addMany, updateOne, removeOne, setAll, ...),
const books = createEntityAdapter();
// createAsyncThunk позволяет работать с асинхронным кодом.
// Например, с запросами к API.
// getBooks работает как набор actions, которые можно диспатчить в приложении.
export const getBooks = createAsyncThunk("get books", async () =>
  await graphqlAPI(`
    query {
      books  {
        id
        title
      }
    }
  `)
);
export const addBook = createAsyncThunk("add book", ({ title }) =>
  graphqlAPI(`
    mutation ($title: string!){
      add_book(objects: { title: $title }) {
        id
        title
      }
    }
  `, { title })
);
// createSlice — обертка над createAction и createReducer.
// Она позволяет работать со стейтом мутабильно.
export const booksSlice = createSlice({
  name: "books",
  initialState: books.getInitialState(),
  extraReducers: {
    // Работаем с результатом запроса getBooks
    [getBooks.fulfilled]: (state, action) => {
      // setAll автоматически создан в createEntityAdapter
      books.setAll(state, action.payload);
    },
    // Работаем с результатом запроса addBook
    [addBook.fulfilled]: (state, action) => {
      // addOne автоматически создан в createEntityAdapter
      books.addOne(state, action.payload);
    },
  },
});
// createEntityAdapter генерирует набор готовых селекторов
// (selectIds, selectById, selectAll, ...)
export const booksSelectors = books.getSelectors((s) => s.books);
export default booksSlice.reducer;
// index.js
import { useDispatch, useSelector } from "react-redux";
import { getBooks, addBook, booksSelectors } from "./booksSlice";
export function Books() {
  const dispatch = useDispatch();
  // booksSelectors.selectAll втоматически создан через createEntityAdapter
  const books = useSelector(booksSelectors.selectAll);
  useEffect(() => {
    dispatch(getBooks());
  }, [dispatch]);
  return (
    <div>
      <button onClick={() => dispatch(addBook({ title: "New Book" }))}>
        Add book
      </button>
      <ul>
        {books.map((b) => <li key={b.id}>{b.title}</li>)}
      </ul>
    </div>
  );
}
Что дальшеПоэкспериментировать с Redux можно локально.
Для настройки окружения достаточно одной команды:
npx create-react-app my-app --template reduxДля Typescript:
npx create-react-app my-app --template redux-typescriptВместо fetch можно воспользоваться библиотекой graphql-request.
Создать бэкенд на GraphQL можно без написания кода.
Для этого подходят такие проекты как hasura или prisma.
===========
 Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, Поисковая оптимизация] SiteAnalyzer 2.3 — Динамика загрузки страниц
 
- [JavaScript, NoSQL, Node.JS] Инструменты Node.js разработчика. Какие ODM нам нужны
 
- [CSS, JavaScript, Интерфейсы, HTML] Динамическое меню c поддержкой touch move и mouse move на RevolveR
 
- [Разработка веб-сайтов, JavaScript, ReactJS] Как эффективно применять React Context (перевод)
 
- [Разработка веб-сайтов, PHP, Laravel] Laravel–Дайджест (12–18 октября 2020)
 
- [Java] Валидация и обработка исключений с помощью Spring (перевод)
 
- [PHP, Конференции, Программирование, Разработка веб-сайтов] 29 ноября в Москве конференция по PHP в России будет офлайн
 
- [Java, Управление персоналом, Софт] How To Build a Password Management Software Using JAVA?
 
- [Разработка веб-сайтов, CSS, TypeScript] Продвинутый CSS-in-TS
 
- [JavaScript, ReactJS, Визуализация данных, Инфографика, Разработка веб-сайтов] Визуализация сложных данных с использованием D3 и React
 
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_api, #_reactjs, #_redux, #_react, #_api, #_graphql, #_reactredux, #_example, #_primer (пример), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_javascript, #_api, #_reactjs
                                        
                                        
                                        
                                     
                                    
                                    
                                                                    
                                                                                             
                         
                        
                            
                                                                    
                                                             
                         
                    
                    
                
                
            
        
    
    
    
    
    
            
    
            
    
        
    
    
        
                        Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
    
    
        
        Текущее время: 04-Ноя 16:40
Часовой пояс: UTC + 5 
            
    
                
| Автор | Сообщение | 
|---|---|
| 
                                
                                
                                                                                                            news_bot ®
                                                                        
                                                                                                                                                 
                                                                            
                                                                                                                
                                            Стаж: 7 лет 8 месяцев                                          | 
                            |
                                ![]() Попробуем соединить Redux и GraphQL без использования Apollo Client или Relay.Что такое ReduxРедакс это архитектурный подход, который реализован в виде небольшой библиотеки. Он предполагает, что у приложения есть хранилище данных state. Изменять хранилище state напрямую нельзя. Это можно сделать только через вспомогательные функции reducers. Псевдокод: function dispatch(action) { 
state = reducer(state, action); } query{ book(id) {} }POST /books {…}POST /graphql mutation{ addBook() {...} }UPDATE /books/id {…}POST /graphql mutation{ updateBook(id) {...} }DELETE /books/idPOST /graphql mutation{ deleteBook(id) {} }GraphQL без Apollo Client (и Relay)Apollo-client это самая популярная библиотека для работы с GraphQL. Она предоставляет интерфейс для работы с запросами внутри компонентов, а также решает задачу хранения кэша. Вместо Redux предполагается использовать внутренние механизмы. Однако эти механизмы далеко не такие простые и удобные.Вместо Apollo Client для примера воспользуемся такой функцией: const graphqlAPI = (query, variables) => fetch("/graphql", { 
method: "POST", body: JSON.stringify({ query, variables }) }); 
 // booksSlice.js 
import { createEntityAdapter, createAsyncThunk, createSlice } from "@reduxjs/toolkit"; // Наш редьюсер будет хранить список книг. // createEntityAdapter генерирует готовый набор функций // для добавления, обновления и удаления книг внутри редьюсера // (addOne, addMany, updateOne, removeOne, setAll, ...), const books = createEntityAdapter(); // createAsyncThunk позволяет работать с асинхронным кодом. // Например, с запросами к API. // getBooks работает как набор actions, которые можно диспатчить в приложении. export const getBooks = createAsyncThunk("get books", async () => await graphqlAPI(` query { books { id title } } `) ); export const addBook = createAsyncThunk("add book", ({ title }) => graphqlAPI(` mutation ($title: string!){ add_book(objects: { title: $title }) { id title } } `, { title }) ); // createSlice — обертка над createAction и createReducer. // Она позволяет работать со стейтом мутабильно. export const booksSlice = createSlice({ name: "books", initialState: books.getInitialState(), extraReducers: { // Работаем с результатом запроса getBooks [getBooks.fulfilled]: (state, action) => { // setAll автоматически создан в createEntityAdapter books.setAll(state, action.payload); }, // Работаем с результатом запроса addBook [addBook.fulfilled]: (state, action) => { // addOne автоматически создан в createEntityAdapter books.addOne(state, action.payload); }, }, }); // createEntityAdapter генерирует набор готовых селекторов // (selectIds, selectById, selectAll, ...) export const booksSelectors = books.getSelectors((s) => s.books); export default booksSlice.reducer; // index.js 
import { useDispatch, useSelector } from "react-redux"; import { getBooks, addBook, booksSelectors } from "./booksSlice"; export function Books() { const dispatch = useDispatch(); // booksSelectors.selectAll втоматически создан через createEntityAdapter const books = useSelector(booksSelectors.selectAll); useEffect(() => { dispatch(getBooks()); }, [dispatch]); return ( <div> <button onClick={() => dispatch(addBook({ title: "New Book" }))}> Add book </button> <ul> {books.map((b) => <li key={b.id}>{b.title}</li>)} </ul> </div> ); } Для настройки окружения достаточно одной команды: npx create-react-app my-app --template reduxДля Typescript: npx create-react-app my-app --template redux-typescriptВместо fetch можно воспользоваться библиотекой graphql-request. Создать бэкенд на GraphQL можно без написания кода. Для этого подходят такие проекты как hasura или prisma. =========== Источник: habr.com =========== Похожие новости: 
 Разработка веб-сайтов ), #_javascript, #_api, #_reactjs  | 
                        |
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
    Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 04-Ноя 16:40
Часовой пояс: UTC + 5