Kombination von Redux und GraphQL mit einem einfachen Beispiel

Versuchen wir, Redux und GraphQL ohne Verwendung von Apollo Client oder Relay zu verbinden. Das ist einfacher als es klingt.

Was ist GraphQL?

GraphQL für den Client ist nur eine POST-Anforderung mit einem speziellen Textformat:

SICH AUSRUHEN

GraphQL

GET / books / id

POST / graphql

query{ book(id) {} }

POST / Bücher

{…}

POST / graphql

mutation{ addBook() {...} }

UPDATE / books / id

{…}

POST / graphql

mutation{ updateBook(id) {...} }

LÖSCHEN / Bücher / ID

POST / graphql

mutation{ deleteBook(id) {} }

GraphQL ohne Apollo Client (und 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. — . :

, .

// 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 , GraphQL. Apollo Client Relay.

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.




All Articles