嗨,我正在编写代码以在自定义钩子中使用axios获取JSON并返回该值,但是即使存在,我也无法访问该对象属性。
我一直试图像item.title
或item["title"]
甚至JSON.parse()
那样访问,但是parse()
返回了跨源错误。
customHooks.js
import { useState, useEffect } from "react";
import axios from "axios";
const GetPost = (id) => {
const [post, setPost] = useState();
useEffect(() => {
axios.get(`http://localhost:8000/post/${id}`).then((res) => setPost(res));
}, []);
return post;
};
export default GetPost;
调用钩子的函数,我想访问该对象:
import React from "react";
import getPost from "../customHooks/GetPost";
import { Jumbotron, Container } from "react-bootstrap";
const PostDetail = (props) => {
const item = getPost(props.match.params.id);
console.log(item); // i can access the object
console.log(item.title); //TypeError: Cannot read property 'title' of undefined
return (
<Jumbotron fluid>
<Container>
{/* <h1>{item.title}</h1>
<p>{item.description}</p> */}
</Container>
</Jumbotron>
);
};
export default PostDetail;
服务器http://localhost:8000/post/post_5e9cbf07b44c7的实际响应是:
{
"message": "success",
"item": {
"post_id": "post_5e9cbf07b44c7",
"title": "Asperiores.",
"description": "Porro iure aliquam laborum veniam quis vel. At itaque voluptas voluptas natus eligendi aut facilis.",
"content": "lorem ipsum",
"img_url": "https://lorempixel.com/100/100/cats/?61693",
"created_by": "user_5e9cbf07b48fc",
"created_at": "2020-04-19 21:13:43",
"updated_at": "2020-04-19 21:13:43"
}
}
PostDetail.js中console.log(item)
的值为:
{
"data": {
"message": "success",
"item": {
"post_id": "post_5e9cbf07b44c7",
"title": "Asperiores.",
"description": "Porro iure aliquam laborum veniam quis vel. At itaque voluptas voluptas natus eligendi aut facilis.",
"content": "lorem ipsum.",
"img_url": "https://lorempixel.com/100/100/cats/?61693",
"created_by": "user_5e9cbf07b48fc",
"created_at": "2020-04-19 21:13:43",
"updated_at": "2020-04-19 21:13:43"
}
},
"status": 200,
"statusText": "OK",
"headers": {
"cache-control": "no-cache, private",
"content-type": "application/json"
},
"config": {
"url": "http://localhost:8000/post/post_5e9cbf07b44c7",
"method": "get",
"headers": {
"Accept": "application/json, text/plain, */*"
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1
},
"request": {}
}
提前感谢:)
答案 0 :(得分:2)
当您尝试访问返回的值时会发生问题,因为在初始渲染时该值不可用,因为该效果在渲染周期后运行,而且因为axios请求是异步的。
但是,如果您实际上将状态初始化为自定义钩子中的对象,它将起作用
还要确保您将res.data.item
设置为状态,而不是res
。发布您可以使用item.title
旁注:
请确保为自定义钩子名称加上use
前缀,这实际上有助于确定自定义钩子或函数之间的区别。
另外,由于您基于参数id进行API调用,因此我建议您将该ID作为依赖传递给自定义钩子中的useEffect,以便ID更改的场景也可以无缝工作
import { useState, useEffect } from "react";
import axios from "axios";
const useGetPost = (id) => {
const [post, setPost] = useState({}); // initialize here
useEffect(() => {
axios.get(`http://localhost:8000/post/${id}`).then((res) => setPost(res.data.item));
}, [id]); // pass id as a dependency here
return post;
};
export default useGetPost;
在PostDetail组件中使用它,例如
import React from "react";
import useGetPost from "../customHooks/GetPost";
import { Jumbotron, Container } from "react-bootstrap";
const PostDetail = (props) => {
const item = useGetPost(props.match.params.id);
console.log(item);
console.log(item.title);
return (
<Jumbotron fluid>
<Container>
{/* <h1>{item.title}</h1>
<p>{item.description}</p> */}
</Container>
</Jumbotron>
);
};
export default PostDetail;