我的组件不显示点击的书籍详细信息

问题描述 投票:0回答:1

当我点击书籍推荐时,我正在工作。它带我到一个名为“书”的新组件。并显示该单书详细信息。但仅当条件正在运行并显示 te 加载时。 我不明白如何解决这个问题。这是我的代码。

import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom'; // Import useNavigate instead of useHistory
import { useDispatch, useSelector } from 'react-redux';
import MenuAppBar from './components/MenuAppBar';
import './Home.css';
import { Search, onSubmit,SingleBookDetails,setSelectedBookId } from './Redux/actions';
import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';
import SingleBook from './components/Book'; // Make sure the path is correct

const Main = () => {
  const dispatch = useDispatch();
  const searchQuery = useSelector((state) => state.search);
  const apiResponse = useSelector((state) => state.apiResponse);
  const BookList = useSelector((state) => state.BookList);
  const selectedBookId = useSelector((state) => state.selectedBookId);
  

  const [inputValue, setInputValue] = useState('');
  const [selectedBook, setSelectedBook] = useState(null);
  const navigate = useNavigate(); // Use useNavigate instead of useHistory

  const handleSearchChange = (value) => {
    setInputValue(value);
    dispatch(Search(value));
  };

  const handleFormSubmit = (value) => {
    dispatch(onSubmit(value));
  };

  const handleBookClick = (book) => {
    console.log('Clicked book:', book);
    setSelectedBook(book);
    // Navigate to the book details page
    
    dispatch(SingleBookDetails(book.id[0]._));
    navigate(`/book-details/${book.id[0]._}`);
  };
  console.log('BookList', BookList);

  return (
    <>
      {/* <BookDetails /> */}
      <div className="home-container">
        <MenuAppBar />

        <div className="centered-search-container">
          <Autocomplete
            freeSolo
            id="combo-box-demo"
            options={apiResponse || []}
            getOptionLabel={(option) => option.best_book[0].title[0]}
            sx={{
              width: 300,
              backgroundColor: '#FFFFFF',
              borderRadius: '8px',
              boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)',
            }}
            onInputChange={(event, newInputValue) => {
              handleSearchChange(newInputValue);
            }}
            onChange={(event, newValue) => {
              // Handle book selection here
              if (newValue) {
                handleBookClick(newValue);
              }
            }}
            renderInput={(params) => <TextField {...params} label="Search Books" />}
          />
          <button
            style={{
              marginLeft: '10px',
              padding: '10px',
              backgroundColor: '#00695C',
              color: 'white',
            }}
            onClick={() => handleFormSubmit(inputValue)}
          >
            Search
          </button>
        </div>
      </div>

      {/* Render the BookDetails component when a book is selected */}
      {/* {selectedBook && <Single bookDetails={selectedBook} />} */}
      {selectedBookId && <SingleBook />}
    </>
  );
};

export default Main;

我的操作文件

 import { parseString } from 'xml2js';

export const Search = (query) => (dispatch) => {
    console.log('Dispatching Search_Query action with payload:', query);
    console.log('Search Query in Redux Action:', query);
    dispatch({
      type: 'SET_SEARCH_QUERY',
      payload: query,
    });
  };
  
 

  export const onSubmit = (inputValue) => async (dispatch) => {
    try {
      // Dispatch the initial action
      dispatch({
        type: 'ON_SUBMIT',
        payload: inputValue,
      });
  
      console.log('Submitting query...', inputValue);
      const apiKey = 'rgMebNe9PaPTpob7TImEw';
      const response = await fetch(`https://www.goodreads.com/search/index.xml?key=${apiKey}&q=${inputValue}`);
      const xmlData = await response.text();
  
      // Convert XML to JSON using xml2js
      parseString(xmlData, (err, result) => {
       
        const bookData = result?.GoodreadsResponse?.search?.[0]?.results?.[0]?.work;
        console.log('Book Data:', bookData);
        // console.log('Dispatching HANDLE_API_RESPONSE action with payload:', bookData);
  
        dispatch({
          type: 'HANDLE_API_RESPONSE',
          payload: bookData,
        });
      });
  
    } catch (error) {
      console.error('Error submitting query:', error.message);
      // Handle the error as needed
      dispatch({
        type: 'HANDLE_API_ERROR',
        payload: error.message,
      });
    }
  };
  export const setSelectedBookId = (bookId) => ({
    type: 'SET_SELECTED_BOOK_ID',
    payload: bookId,
  });
  
  

  export const SingleBookDetails = (bookId) => async (dispatch) => {
    try {
      const apiKey = 'rgMebNe9PaPTpob7TImEw';
      const response = await fetch(`https://www.goodreads.com/book/show/${bookId}.xml?key=${apiKey}`);
      const xmlData = await response.text();
      console.log('XML Data:', xmlData);
  
      // Convert XML to JSON using xml2js
      parseString(xmlData, (err, result) => {
        const bookDetails = result?.GoodreadsResponse?.book?.[0];
        console.log('Book Details:', bookDetails);
  
        dispatch({
          type: 'FETCH_BOOK_DETAILS_SUCCESS',
          payload: { id: bookId, data: bookDetails },
        });
      });
    } catch (error) {
      console.error('Error fetching book details:', error.message);
      dispatch({
        type: 'FETCH_BOOK_DETAILS_FAILURE',
        payload: error.message,
      });
    }
  };

我的书籍文件。该文件仅显示 if 条件:

import React from 'react';
import { useSelector } from 'react-redux';

const SingleBook = () => {
  // Use useSelector to get state from the Redux store
  const selectedBookId = useSelector((state) => state.selectedBookId);
  const bookDetails = useSelector((state) => state.bookDetails[selectedBookId]);
  console.log('Selected Book ID:', selectedBookId);

  console.log('BookDetailsssss:', bookDetails);

  if (!bookDetails) {
    return <div>Loading...!!!</div>;
  }

  const book = bookDetails.work[0];
  console.log('Bookeeeeee:', book);

  const title = book.original_title[0];
  const author = book.authors[0].author[0].name[0];
  const averageRating = book.average_rating[0];
  const ratingsCount = book.ratings_count[0];
  const imageUrl = book.small_image_url[0];
  const description = book.description[0];
  const link = book.link[0];

  return (
    <div>
      <h1>{title}</h1>
      <p>Author: {author}</p>
      <p>Average Rating: {averageRating}</p>
      <p>Ratings Count: {ratingsCount}</p>
      <img src={imageUrl} alt={title} />
      <p>Description: {description}</p>
      <p>
        <a href={link} target="_blank" rel="noopener noreferrer">
          More Details on Goodreads
        </a>
      </p>
    </div>
  );
};

export default SingleBook;

这是我的减速器文件。

const initialState = {
    search: null,
    submittedValue: null,
    bookList:[],
    bookDetails:[],
    apiResponse: [],
    error: null,
  };
  
  const reducer = (state = initialState, action) => {
    switch (action.type) {
      case 'SET_SEARCH_QUERY':
        return {
          ...state,
          search: action.payload,
        };
      case 'ON_SUBMIT':
        console.log('Form submitted!');
        return {
          ...state,
          submittedValue: action.payload,
        };
        case 'SET_SELECTED_BOOK_ID':
  return {
    ...state,
    selectedBookId: action.payload,
  };
      case 'HANDLE_API_RESPONSE':
        console.log('API Response:', action.payload);
  
        // Extract book names from the API response
        const bookData = action.payload || [];
        const BookList = bookData.map(book => ({
          id: book.id[0]._,
          title: book.best_book[0].title[0],
          author: book.best_book[0].author[0].name[0],
        }));

        
 
        return {
          ...state,
          apiResponse:bookData,
          BookList: BookList,
          error: null,
        };
      case 'HANDLE_API_ERROR':
        console.error('API Error:', action.payload);
        return {
          ...state,
          error: action.payload,
        };
        case 'FETCH_BOOK_DETAILS_SUCCESS':
          return {
            ...state,
            bookDetails: {
              ...state.bookDetails,
              [action.payload.id]: action.payload.data,
            },
            error: null,
          };
        case 'FETCH_BOOK_DETAILS_FAILURE':
          return {
            ...state,
            error: action.payload,
          };
      default:
        return state;
    }
  };
  
  export default reducer;

我尝试在不调用selectorbookId的情况下执行此操作,但它不起作用并给出

 cannot read properties of reading 0
的错误。我期望当我单击特定书籍时,它将在书籍组件中显示单本书的详细信息。

reactjs react-redux
1个回答
0
投票

在 Main 组件中,您将调度 SingleBookDetails 操作来获取书籍详细信息,并使用

selectedBookId
有条件地呈现 SingleBook 组件。单击一本书时,您不会调度
setSelectedBookId
操作。

© www.soinside.com 2019 - 2024. All rights reserved.