将Redux和GraphQL与一个简单示例结合

让我们尝试在不使用Apollo Client或Relay的情况下连接Redux和GraphQL。这比听起来容易。

什么是GraphQL

客户端的GraphQL只是具有特殊正文格式的POST请求:

休息

GraphQL

GET /书籍/ ID

POST / graphql

query{ book(id) {} }

POST /书籍

{…}

POST / graphql

mutation{ addBook() {...} }

更新/书籍/ ID

{…}

POST / graphql

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

删除/书籍/ ID

POST / graphql

mutation{ deleteBook(id) {} }

没有Apollo客户端(和中继)的GraphQL

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