简体   繁体   English

无法访问自定义挂钩中从 axios 返回的 object 值

[英]Cant access object value returned from axios in custom hooks

Hi I'm writing code to get JSON with axios in custom hooks and return the value, but I can't access the object property even it was there.嗨,我正在编写代码来获取 JSON 和 axios 在自定义挂钩中并返回值,但我无法访问 object 属性,即使它在那里。

I have been trying to access like item.title or item["title"] and even JSON.parse() but parse() returned cross origin error.我一直在尝试访问item.titleitem["title"]甚至JSON.parse()parse()返回跨源错误。

customHooks.js 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;

Function where hook is called and I want to access the object: Function 调用钩子,我想访问 object:

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;

The actual response from server http://localhost:8000/post/post_5e9cbf07b44c7 is:来自服务器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"
    }
}

The value of console.log(item) in PostDetail.js is: 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": {}
}

thanks in advance:)提前致谢:)

The problem happens when you try to access the returned value because on initial render the value is not available since the effect runs post render cycle and also because the axios request is async.当您尝试访问返回的值时会出现问题,因为在初始渲染时该值不可用,因为效果在渲染周期后运行,并且还因为 axios 请求是异步的。

It will however work if you actually initialize the state to object within your custom hook但是,如果您在自定义挂钩中实际将 state 初始化为 object,它将起作用

Also make sure that you set res.data.item in the state and not res .还要确保在 state 中设置res.data.item而不是res Post that you can get the value with item.title发布您可以使用item.title获取值

SideNotes:旁注:

Please ensure that you prefix your custom hooks names with use which actually helps eslint figure out the distinction between custom hook or a function.请确保在自定义钩子名称前加上use这实际上有助于 eslint 找出自定义钩子或 function 之间的区别。

Also since you are making an API call based on param id, I advice you to pass that id as a dependency to useEffect in custom hook so that the scenarios where id is changed also work seamlessly此外,由于您正在基于参数 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;

Use it in PostDetail component like在 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM