简体   繁体   中英

I am getting the below error when I am trying to open a product from HomeScreen - Converting circular structure to JSON -->

when I click on a product from HomeScreen.js which should take me to the ProductScreen to show product details but I am getting the below error.

Converting circular structure to JSON --> starting at object with constructor 'NativeTopology' | property 's' -> object with constructor 'Object' | property 'sessionPool' -> object with constructor 'ServerSessionPool' --- property 'topology' closes the circle

The following is the code I am running

ProductConstants.js
export const PRODUCT_DETAILS_REQUEST = "PRODUCT_DETAILS_REQUEST";

export const PRODUCT_DETAILS_SUCCESS = "PRODUCT_DETAILS_SUCCESS";

export const PRODUCT_DETAILS_FAIL = "PRODUCT_DETAILS_FAIL";


productDetailsReducer --Reducer
import {
  PRODUCT_DETAILS_REQUEST,
  PRODUCT_DETAILS_SUCCESS,
  PRODUCT_DETAILS_FAIL,
} from "../constants/productConstants";

export const productDetailsReducer = (
  state = { product: { reviews: [] } },
  action
) => {
  switch (action.type) {
    case PRODUCT_DETAILS_REQUEST:
      return { loading: true, ...state };
    case PRODUCT_DETAILS_SUCCESS:
      return { loading: false, product: action.payload };
    case PRODUCT_DETAILS_FAIL:
      return { loading: false, error: action.payload };
    default:
      return state;
  }
};





 listProductDetails -- Action
import axios from "axios";
import {
  PRODUCT_DETAILS_REQUEST,
  PRODUCT_DETAILS_SUCCESS,
  PRODUCT_DETAILS_FAIL,
} from "../constants/productConstants";

export const listProductDetails = (id) => async (dispatch) => {
  try {
    dispatch({ type: PRODUCT_DETAILS_REQUEST });

    const { data } = await axios.get(`/api/products/${id}`);

    dispatch({
      type: PRODUCT_DETAILS_SUCCESS,
      payload: data,
    });
  } catch (error) {
    dispatch({
      type: PRODUCT_DETAILS_FAIL,
      payload:
        error.response && error.response.data.message
          ? error.response.data.message
          : error.message,
    });
  }
};


ProductScreen.js

import React, { useEffect } from "react";
import { Link } from "react-router-dom";
import { Row, Col, ListGroup, Image, Button, Card } from "react-bootstrap";
import Ratings from "../components/Ratings";
import { useDispatch, useSelector } from "react-redux";
import { listProductDetails } from "../actions/productActions";
import Loader from "../components/loader";
import Message from "../components/message";

const ProductScreen = ({ match }) => {
  const dispatch = useDispatch();

  const productDetails = useSelector((state) => state.productDetails);

  const { loading, error, product } = productDetails;

  useEffect(() => {
    dispatch(listProductDetails(match.params.id));
  }, [dispatch, match]);

  return (
    <>
      <Link className="btn btn-light my-3" to="/">
        Go Back
      </Link>
      {loading ? (
        <Loader />
      ) : error ? (
        <Message>{error}</Message>
      ) : (
        <Row>
          <Col md={6}>
            <Image src={product.image} alt={product.name} fluid />
          </Col>
          <Col md={3}>
            <ListGroup variant="flush">
              <ListGroup.Item>
                <h3>{product.name}</h3>
              </ListGroup.Item>
              <ListGroup.Item>
                <Ratings
                  value={product.rating}
                  text={`${product.numReviews} reviews`}
                />
              </ListGroup.Item>
              <ListGroup.Item>Price: ${product.price}</ListGroup.Item>
              <ListGroup.Item>
                Description: ${product.description}
              </ListGroup.Item>
            </ListGroup>
          </Col>
          <Col md={3}>
            <Card>
              <ListGroup variant="flush">
                <ListGroup.Item>
                  <Col>Price:</Col>
                  <Col>
                    <strong>{product.price}</strong>
                  </Col>
                </ListGroup.Item>

                <ListGroup.Item>
                  <Col>Stock:</Col>
                  <Col>
                    {product.countInStock > 0 ? "In Stock" : "Out of Stock"}
                  </Col>
                </ListGroup.Item>

                <ListGroup.Item>
                  <Button
                    class="btn btn-block"
                    type="button"
                    disabled={product.countInStock === 0}
                  >
                    Add to Cart
                  </Button>
                </ListGroup.Item>
              </ListGroup>
            </Card>
          </Col>
        </Row>
      )}
    </>
  );
};

export default ProductScreen;

The reason why you get this issue is that one of the objects you pass as a second argument to your function has a circular reference(s) to itself or to other objects that point to that object. If not all of them have circular references, you can wrap the serialization with try/catch to save your program from crashing.

Consequently, we get a runtime error saying we have circular references:

Uncaught TypeError: Converting circular structure to JSON --> starting at object with constructor 'Object' | property 'someRef' -> object with constructor 'Object' --- property 'someRef' closes the circle

That's because JSON can't serialize cyclic data structures by design.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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