开始使用 React
¥Getting Started with React
Strapi 文档团队专注于改进 Strapi 5 核心体验的文档。我们将在未来 6 个月内发布许多更改,请密切关注👀。
¥The Strapi Documentation team focuses on improving the documentation for Strapi 5's core experience. We will release many changes in the next 6 months, so please keep an eye out 👀.
因此,当前页面现在仅处于维护模式,可能未完全与 Strapi 5 保持同步,并且很快将被 React(可能还有 Next.js)集成指南取代。这将是 Strapi 文档团队将维护的唯一官方集成指南。
¥As a result, the present page is now in maintenance mode only, might not be fully up-to-date with Strapi 5, and will soon be replaced by a React (and possibly Next.js) integration guide. This will be the only official integration guide that the Strapi Documentation team will maintain.
完成后,你将在 Strapi 的 集成页面 上找到其他集成指南。
¥You will find other integration guides on Strapi's integrations page when it's done.
本集成指南遵循 快速入门指南。你应该能够通过浏览 URL http://localhost:1337/api/restaurants 使用该 API。
¥This integration guide follows the Quick Start Guide. You should be able to consume the API by browsing the URL http://localhost:1337/api/restaurants.
如果你尚未阅读快速入门指南,则使用 React 请求 Strapi API 的方式将保持不变,只是你不会获取相同的内容。
¥If you haven't gone through the Quick Start Guide, the way you request a Strapi API with React remains the same except that you will not fetch the same content.
创建一个反应应用
¥Create a React app
使用 create-react-app 创建一个基本的 React 应用。
¥Create a basic React application using create-react-app.
- yarn
- npm
yarn create react-app react-app
npx create-react-app react-app
使用 HTTP 客户端
¥Use an HTTP client
许多 HTTP 客户端都可用,但本文档中提供了使用 Axios 和 拿来 的示例。
¥Many HTTP clients are available but in this documentation there are examples using Axios and Fetch.
安装 axios:
¥To install Axios:
- yarn
- npm
yarn add axios
npm install axios
Fetch
无需安装。
¥There is no installation required for Fetch
.
GET 请求你的集合类型
¥GET Request your collection type
对 restaurant
集合类型执行 GET
请求以获取所有餐厅。
¥Execute a GET
request on the restaurant
collection type in order to fetch all your restaurants.
确保你激活了 restaurant
集合类型的 find
权限
¥Be sure that you activated the find
permission for the restaurant
collection type
- axios
- fetch
import axios from "axios";
axios.get("http://localhost:1337/api/restaurants").then((response) => {
console.log(response);
});
fetch("http://localhost:1337/api/restaurants", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
})
.then((response) => response.json())
.then((data) => console.log(data));
{
"data": [
{
"id": 2,
"documentId": "na8ce9ltc0y99syjbs3vbigx",
"Name": "Biscotte Restaurant",
"Description": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers."
}
]
}
],
"createdAt": "2024-08-09T08:59:05.114Z",
"updatedAt": "2024-08-09T08:59:06.341Z",
"publishedAt": "2024-08-09T08:59:06.344Z",
"locale": "en"
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}
示例
¥Example
- axios
- fetch
./src/App.js
import axios from "axios";
import { useEffect, useState } from "react";
const App = () => {
const [error, setError] = useState(null);
const [restaurants, setRestaurants] = useState([]);
useEffect(() => {
axios
.get("http://localhost:1337/api/restaurants")
.then(({ data }) => setRestaurants(data.data))
.catch((error) => setError(error));
}, []);
if (error) {
// Print errors if any
return <div>An error occured: {error.message}</div>;
}
return (
<div className="App">
<ul>
{restaurants.map(({ id, attributes }) => (
<li key={id}>{attributes.Name}</li>
))}
</ul>
</div>
);
};
export default App;
./src/App.js
import { useEffect, useState } from "react";
// Parses the JSON returned by a network request
const parseJSON = (resp) => (resp.json ? resp.json() : resp);
// Checks if a network request came back fine, and throws an error if not
const checkStatus = (resp) => {
if (resp.status >= 200 && resp.status < 300) {
return resp;
}
return parseJSON(resp).then((resp) => {
throw resp;
});
};
const headers = { "Content-Type": "application/json" };
const App = () => {
const [error, setError] = useState(null);
const [restaurants, setRestaurants] = useState([]);
useEffect(() => {
fetch("http://localhost:1337/api/restaurants", { headers, method: "GET" })
.then(checkStatus)
.then(parseJSON)
.then(({ data }) => setRestaurants(data.data))
.catch((error) => setError(error));
}, []);
if (error) {
// Print errors if any
return <div>An error occured: {error.message}</div>;
}
return (
<div className="App">
<ul>
{restaurants.map(({ id, attributes }) => (
<li key={id}>{attributes.Name}</li>
))}
</ul>
</div>
);
};
export default App;
POST 请求你的集合类型
¥POST Request your collection type
对 restaurant
集合类型执行 POST
请求以创建餐厅。
¥Execute a POST
request on the restaurant
collection type in order to create a restaurant.
确保你激活了 restaurant
集合类型的 create
权限和 category
集合类型的 find
权限。
¥Be sure that you activated the create
permission for the restaurant
collection type and the find
permission fot the category
Collection type.
在此示例中,已创建 japanese
类别,其 ID 为:3.
¥In this example a japanese
category has been created which has the id: 3.
- axios
- fetch
import axios from "axios";
axios
.post("http://localhost:1337/api/restaurants", {
data: {
"Name": "Dolemon Sushi",
"Description": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers."
}
]
}
],
categories: [3],
},
})
.then((response) => {
console.log(response);
});
fetch("http://localhost:1337/api/restaurants", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
data: {
"Name": "Dolemon Sushi",
"Description": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers."
}
]
}
],
categories: [3],
},
}),
})
.then((response) => response.json())
.then((data) => console.log(data));
{
"data": {
"id": 3,
"documentId": "jm8rm7jl9ncalk12lkc4bhcx"
"name": "Dolemon Sushi",
"description": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers."
}
]
}
],
"createdAt": "2024-03-02T21:40:39.185Z",
"updatedAt": "2024-03-02T21:40:39.185Z",
"publishedAt": "2024-03-02T21:40:39.118Z",
"locale": "en"
},
"meta": {}
}
示例
¥Example
- axios
- fetch
./src/App.js
import axios from "axios";
import { useCallback, useEffect, useState, useId } from "react";
const Checkbox = ({ name, isChecked, onAddCategory, onRemoveCategory }) => {
const id = useId();
return (
<div>
<label htmlFor={id}>{name}</label>
<input
type="checkbox"
checked={isChecked}
onChange={isChecked ? onRemoveCategory : onAddCategory}
name="categories"
id={id}
/>
</div>
);
};
const App = () => {
const [allCategories, setAllCategories] = useState([]);
const [error, setError] = useState(null);
const [modifiedData, setModifiedData] = useState({
categories: [],
description: "",
name: "",
});
const handleInputChange = useCallback(({ target: { name, value } }) => {
setModifiedData((prevData) => ({ ...prevData, [name]: value }));
}, []);
const handleSubmit = async (e) => {
e.preventDefault();
await axios
.post("http://localhost:1337/api/restaurants", { data: modifiedData })
.then((response) => {
console.log(response);
})
.catch((error) => {
setError(error);
});
};
useEffect(() => {
axios
.get("http://localhost:1337/api/categories")
.then(({ data }) => {
setAllCategories(data.data);
console.log(data.data);
})
.catch((error) => setError(error));
}, []);
if (error) {
// Print errors if any
return <div>An error occured: {error.message}</div>;
}
return (
<div className="App">
<form onSubmit={handleSubmit}>
<h3>Restaurants</h3>
<br />
<label>
Name:
<input
type="text"
name="name"
onChange={handleInputChange}
value={modifiedData.name}
/>
</label>
<label>
Description:
<input
type="text"
name="description"
onChange={handleInputChange}
value={modifiedData.description}
/>
</label>
<div>
<br />
<b>Select categories</b>
{allCategories.map(({ id, attributes }) => (
<Checkbox
key={id}
name={attributes.Name}
isChecked={modifiedData.categories.includes(id)}
onAddCategory={() => {
const nextData = {
...modifiedData,
categories: [...modifiedData.categories, id],
};
setModifiedData(nextData);
}}
onRemoveCategory={() => {
const nextData = {
...modifiedData,
categories: modifiedData.categories.filter(
(catId) => catId !== id
),
};
setModifiedData(nextData);
}}
/>
))}
</div>
<br />
<button type="submit">Submit</button>
</form>
</div>
);
};
export default App;
./src/App.js
import { useCallback, useEffect, useState, useId } from "react";
// Parses the JSON returned by a network request
const parseJSON = (resp) => (resp.json ? resp.json() : resp);
// Checks if a network request came back fine, and throws an error if not
const checkStatus = (resp) => {
if (resp.status >= 200 && resp.status < 300) {
return resp;
}
return parseJSON(resp).then((resp) => {
throw resp;
});
};
const headers = { "Content-Type": "application/json" };
const Checkbox = ({ name, isChecked, onAddCategory, onRemoveCategory }) => {
const id = useId();
return (
<div>
<label htmlFor={id}>{name}</label>
<input
type="checkbox"
checked={isChecked}
onChange={isChecked ? onRemoveCategory : onAddCategory}
name="categories"
id={id}
/>
</div>
);
};
const App = () => {
const [allCategories, setAllCategories] = useState([]);
const [error, setError] = useState(null);
const [modifiedData, setModifiedData] = useState({
categories: [],
description: "",
name: "",
});
const handleInputChange = useCallback(({ target: { name, value } }) => {
setModifiedData((prevData) => ({ ...prevData, [name]: value }));
}, []);
const handleSubmit = async (e) => {
e.preventDefault();
await fetch("http://localhost:1337/api/restaurants", {
headers,
method: "POST",
body: JSON.stringify({ data: modifiedData }),
})
.then((response) => {
console.log(response);
})
.catch((error) => {
setError(error);
});
};
useEffect(() => {
fetch("http://localhost:1337/api/categories", { headers, method: "GET" })
.then(checkStatus)
.then(parseJSON)
.then(({ data }) => setAllCategories(data))
.catch((error) => setError(error));
}, []);
if (error) {
// Print errors if any
return <div>An error occured: {error.message}</div>;
}
return (
<div className="App">
<form onSubmit={handleSubmit}>
<h3>Restaurants</h3>
<br />
<label>
Name:
<input
type="text"
name="name"
onChange={handleInputChange}
value={modifiedData.name}
/>
</label>
<label>
Description:
<input
type="text"
name="description"
onChange={handleInputChange}
value={modifiedData.description}
/>
</label>
<div>
<br />
<b>Select categories</b>
{allCategories.map(({ id, attributes }) => (
<Checkbox
key={id}
name={attributes.Name}
isChecked={modifiedData.categories.includes(id)}
onAddCategory={() => {
const nextData = {
...modifiedData,
categories: [...modifiedData.categories, id],
};
setModifiedData(nextData);
}}
onRemoveCategory={() => {
const nextData = {
...modifiedData,
categories: modifiedData.categories.filter(
(catId) => catId !== id
),
};
setModifiedData(nextData);
}}
/>
))}
</div>
<br />
<button type="submit">Submit</button>
</form>
</div>
);
};
export default App;
PUT 请求你的集合类型
¥PUT Request your collection type
对 restaurant
集合类型执行 PUT
请求以更新餐厅的类别。
¥Execute a PUT
request on the restaurant
collection type in order to update the category of a restaurant.
确保你激活了 restaurant
集合类型的 put
权限。
¥Be sure that you activated the put
permission for the restaurant
collection type.
我们认为你的餐厅 ID 为 2
,你的类别 ID 为 2
。
¥We consider that the id of your restaurant is 2
, and the id of your category is 2
.
- axios
- fetch
import axios from "axios";
axios
.put("http://localhost:1337/api/restaurants/2", {
data: {
categories: [2],
},
})
.then((response) => {
console.log(response);
});
fetch("http://localhost:1337/api/restaurants/3", {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
data: {
categories: [2],
},
}),
})
.then((response) => response.json())
.then((data) => {
console.log(data);
});
{
"data": {
"id": 3,
"documentId": "jm8rm7jl9ncalk12lkc4bhcx"
"name": "Dolemon Sushi",
"description": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers."
}
]
}
],
"createdAt": "2024-03-02T21:40:39.185Z",
"updatedAt": "2024-03-02T21:40:39.185Z",
"publishedAt": "2024-03-02T21:40:39.118Z",
"locale": "en"
},
"meta": {}
}