redux 如何在react中使用useSelector钩子调用对象

ndh0cuux  于 2023-02-04  发布在  React
关注(0)|答案(1)|浏览(138)

我正在尝试获取另一个组件中的对象数组,即-Animearray,但在控制台中收到未定义的错误。以下是Store组件的代码

import {
  configureStore,
  createAsyncThunk,
  createSlice,
} from "@reduxjs/toolkit";
import { API_KEY, TMBD_BASE_URL } from "../utils/constent";
import axios from "axios";
const initialState = {
  movies: [],
  genresLoaded: false,
  genres: [],
};
const initialAnime = {
  anime: [],
  genresLoaded: false,
  genres: [],
};

const createArrayfromRawdata = (array, moviesArray, genres) => {
  array.forEach((movie) => {
    const movieGenres = [];
    movie.genre_ids.forEach((genre) => {
      const name = genres.find(({ id }) => id === genre);
      if (name) movieGenres.push(name.name);
    });
    if (movie.backdrop_path)
      moviesArray.push({
        id: movie.id,
        name: movie?.original_name ? movie.original_name : movie.original_title,
        image: movie.backdrop_path,
        genres: movieGenres.slice(0, 3),
      });
  });
};
async function createAnimeFromRawData(rawData, animeArray) {
  const data = rawData;
  console.log(animeArray);
  for (let i = 0; i < data.length; i++) {
    const anime = data[i];
    if (anime) {
      const genreArr = anime.genres.map((genre) => genre.name);
      animeArray.push({
        name: anime.title,
        genre: genreArr,
        score: anime.score,
        image: anime.images.jpg.image_url,
        trailer: anime.trailer.embed_url,
        episodes: anime.episodes,
        synopsis: anime.synopsis,
      });
    }
  }
  console.log(animeArray);
  return animeArray;
}

export const RawdataAnime = async () => {
  const Animearray = [];
  for (let i = 1; Animearray.length < 60 && i < 10; i++) {
    const { data } = await axios.get(`https://api.jikan.moe/v4/top/anime`); // Equivalent to response.data
    const results = data?.data || [];

    try {
      await createAnimeFromRawData(results, Animearray);
      await new Promise((resolve) => setTimeout(resolve, 1000));
    } catch (error) {
      console.error(error);
    }
  }
  return Animearray;
};

const rawData = async (api, genres, paging) => {
  const moviesArray = [];
  for (let i = 1; moviesArray.length < 60 && i < 10; i++) {
    const {
      data: { results },
    } = await axios.get(`${api}${paging ? `&page=${i}` : ""}`);
    createArrayfromRawdata(results, moviesArray, genres);
  }
  return moviesArray;
};
export const fetchMovies = createAsyncThunk(
  "neflix/trending",
  async ({ type }, thunkAPI) => {
    const {
      netflix: { genres },
    } = thunkAPI.getState();
    return rawData(
      `${TMBD_BASE_URL}/trending/${type}/week?api_key=${API_KEY}`,
      genres,
      true
    );
  }
);

//`${TMBD_BASE_URL}/discover/${type}?api_key=${API_KEY}&with_genres=${genres}`
export const getGenres = createAsyncThunk("netflix/genres", async () => {
  const {
    data: { genres },
  } = await axios.get(`${TMBD_BASE_URL}/genre/movie/list?api_key=${API_KEY}`);

  return genres;
});

const netflixSlice = createSlice({
  name: "netflix",
  initialState,
  extraReducers: (builder) => {
    builder.addCase(getGenres.fulfilled, (state, action) => {
      state.genres = action.payload;
      state.genresLoaded = true;
    });
    builder.addCase(fetchMovies.fulfilled, (state, action) => {
      state.movies = action.payload;
    });
  },
});

const animeSlice = createSlice({
  name: "anime",
  initialState: initialAnime,
  extraReducers: (builder) => {
    builder.addCase(RawdataAnime.fulfilled, (state, action) => {
      state.anime = action.payload;
    });
  },
});
export const store = configureStore({
  reducer: {
    netflix: netflixSlice.reducer,
    anime: animeSlice.reducer,
  },
});

结果当我尝试在主组件中使用animeArray时,它没有加载

import BackgroundVid from "../components/BackgroundVid";
import { fetchMovies, getGenres, RawdataAnime, setAnime } from "../store";

import Slider from "../components/Slider";

export default function Netflix() {
  const [scrolled, isScrolled] = useState(false);
  const genresLoaded = useSelector((state) => state.netflix.genresLoaded);
  const movies = useSelector((state) => state.netflix.movies);
  const anime = useSelector((state) => state.anime.anime);
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(getGenres());
    onAuthStateChanged(firbaseauth, (user) => {
      if (user) {
        setUser(user);
      } else {
        setUser(null);
      }
    });
  }, []);
  useEffect(() => {
    if (genresLoaded) {
      dispatch(fetchMovies({ type: "all" }));
    }
  });

如果你对如何从该组件获取数据有任何建议,请告诉我。目标数据存储在组件中,作为animeArray

8wtpewkr

8wtpewkr1#

据我所知,RawdataAnime函数不是一个动作创建器,如果你想有一个RawdataAnime.fulfilled reducer case,那么它应该被转换成一个异步动作,这样当返回的Promise解析时,也就是说,它被实现了,reducer就可以处理返回的有效负载。
示例:存储

import {
  configureStore,
  createAsyncThunk,
  createSlice,
} from "@reduxjs/toolkit";
import axios from "axios";

const initialAnime = {
  anime: [],
  genresLoaded: false,
  genres: [],
};

...

function createAnimeFromRawData(rawData) {
  return rawData.map((anime) => ({
    id: anime.mal_id,
    name: anime.title,
    genre: anime.genres.map((genre) => genre.name),
    score: anime.score,
    image: anime.images.jpg.image_url,
    trailer: anime.trailer.embed_url,
    episodes: anime.episodes,
    synopsis: anime.synopsis
  }));
}

export const RawdataAnime = createAsyncThunk("anime/fetchAnime", async () => {
  const { data } = await axios.get(`https://api.jikan.moe/v4/top/anime`); // Equivalent to response.data
  const results = data?.data || [];
  return createAnimeFromRawData(results);
});

...

const animeSlice = createSlice({
  name: "anime",
  initialState: initialAnime,
  extraReducers: (builder) => {
    builder.addCase(RawdataAnime.fulfilled, (state, action) => {
      state.anime = action.payload;
    });
  }
});

export const store = configureStore({
  reducer: {
    netflix: netflixSlice.reducer,
    anime: animeSlice.reducer
  }
});

应用程序

const dispatch = useDispatch();
const anime = useSelector((state) => state.anime.anime);

useEffect(() => {
  dispatch(RawdataAnime());
}, []);

相关问题