
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
|
POST / Bücher
| POST / graphql
|
UPDATE / books / id
| POST / graphql
|
LÖSCHEN / Bücher / ID | POST / graphql
|
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. — . :
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 , 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.