让我们尝试在不使用Apollo Client或Relay的情况下连接Redux和GraphQL。这比听起来容易。
什么是GraphQL
客户端的GraphQL只是具有特殊正文格式的POST请求:
休息 | GraphQL |
---|---|
GET /书籍/ ID | POST / graphql
|
POST /书籍
| POST / graphql
|
更新/书籍/ ID
| POST / graphql
|
删除/书籍/ ID | POST / graphql
|
没有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. — . :
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.