현재 작업 중인 netflix 의 movieSlice부분,,
약간 어려운 부분이 있어서 chat Gpt로 코드에 대한 설명을 들었다.
그리고 개선된 방법까지 알고 싶어서 물어봤다.
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
import { TMDB_BASE_URL, API_KEY } from "../../util/constants";
const initialState = {
movies: [],
genresLoded: false,
genres: [],
};
//영화의 장르의 목록을 가져온다.
export const getGenres = createAsyncThunk("movie/genres", async () => {
const {
data: { genres },
} = await axios.get(`${TMDB_BASE_URL}/genre/movie/list?api_key=${API_KEY}`);
return genres;
});
// 인기 있는 영화 데이터를 가져옴 fetch
//type으로 영화의 유형을 정할 수 잇고
//thunkAPI 매개변수를 통해 현재 Redux 상태를 액세스할 수 있습니다. thunkAPI.getState()를 통해 현재 상태에서 netflix.genres를 가져옴
export const fetchMovies = createAsyncThunk(
"movie/trending",
async ({ type }, thunkApi) => {
const {
movie: { genres },
} = thunkApi.getState();
return getRawData(
`${TMDB_BASE_URL}/trending/${type}/week?api_key=${API_KEY}`,
genres,
true
);
}
);
// 주어진 엔드포인트에서 영화 데이터를 가져오는 기능수행
const getRawData = async (api, genres, paging = false) => {
//api 매개변수는 엔드포인트 URL을 나타내며, genres 매개변수는 장르 목록을 전달.
//paging 매개변수는 페이지네이션을 사용할지 여부
const moviesArr = [];
//영화 배열의 길이가 60개가 되거나 페이지의 번호가 10을 초과할때까지 진행
for (let i = 1; moviesArr.length < 60 && i < 10; i++) {
const {
data: { results },
} = await axios.get(`${api}${paging ? `&page=${i}` : ""}`);
createArrFromRawData(results, moviesArr, genres);
}
return moviesArr;
};
//주어딘 데이터 배열과 장르 목록을 기반으로 영화 정보를 가공
const createArrFromRawData = (resultsArr, moviesArr, genres) => {
//결과로 받은 영화를 순회하면서각 장르의 id확인, 해당 장르와 일치하는 장르 이름을 찾아 //영화 장르 배열에 추가 최대 3개
resultsArr.forEach((movie) => {
const movieGenres = [];
movie.genres_ids.forEach((genre) => {
const name = genres.find(({ id }) => id === genre);
if (name) movieGenres.push(name.name);
});
if (movie.backdrop_path)
moviesArr.push({
id: movie.id,
name: movie?.original_name
? movie?.original_name
: movie.original_title,
image: movie.backdrop_path,
genres: movieGenres.slice(0, 3),
});
});
};
const movieSlice = createSlice({
name: "movie",
initialState,
extraReducers: (builder) => {
builder.addCase(getGenres.fulfilled, (state, action) => {
state.genres = action.payload;
state.genresLoded = true;
});
builder.addCase(fetchMovies.fulfilled, (state, action) => {
state.movies = action.payload;
});
},
});
export default movieSlice.reducer;
import { TMDB_BASE_URL, API_KEY } from "./constants";
const generateApiUrl = (path, queryParams = {}) => {
//path 는 식별자
const queryString = new URLSearchParams(queryParams).toString();
return `${TMDB_BASE_URL}/${path}?api_key=${API_KEY}${queryString ? `&${queryString}`: ''}`;
};
export default generateApiUrl;
export const getGenres = createAsyncThunk("movie/genres", async () => {
const url = generateApiUrl("/genre/movie/list");
const {
data: { genres },
} = await axios.get(url);
console.log("genres", genres);
return genres;
});
export const fetchMovies = createAsyncThunk(
"movie/trending",
async ({ type }, thunkApi) => {
const url = generateApiUrl(`/trending/${type}/week`);
const {
movie: { genres },
} = thunkApi.getState();
return getRawData(url, genres, true);
}
);
return getRawData(url, genres);
export const fetchMovies = createAsyncThunk("movie/trending", async ({ type }, thunkApi) => {
const {
movie: { genres },
} = thunkApi.getState();
//현재 저장된 장르를 가져옴..
const apiUrl = generateApiUrl(`trending/${type}/week`);
const movies = await getRawData(apiUrl, genres);
return movies;
});
const getRawData = async (api, genres) => {
const moviesArr = [];
for (let page = 1; moviesArr.length < 60 && page < 10; page++) {
const { data: { results } } = await axios.get(api, { params: { page } });
createArrFromRawData(results, moviesArr, genres);
}
return moviesArr;
};
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
import generateApiUrl from "../../util/generateApiUrl";
const initialState = {
movies: [],
genresLoaded: false,
genres: [],
};
export const getGenres = createAsyncThunk("movie/genres", async () => {
const url = generateApiUrl("/genre/movie/list");
const {
data: { genres },
} = await axios.get(url);
console.log("genres", genres);
return genres;
});
export const fetchMovies = createAsyncThunk(
"movie/trending",
async ({ type }, thunkApi) => {
const {
movie: { genres },
} = thunkApi.getState();
const apiUrl = generateApiUrl(`trending/${type}/week`);
const movies = await getRawData(apiUrl, genres);
console.log('movies',movies);
return movies;
}
);
const getRawData = async (api, genres) => {
const moviesArr = [];
for (let page = 1; moviesArr.length < 60 && page < 10; page++) {
const {
data: { results },
} = await axios.get(api, { params: { page } });
createArrFromRawData(results, moviesArr, genres);
}
return moviesArr;
};
const createArrFromRawData = (resultsArr, moviesArr, genres) => {
resultsArr.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) {
moviesArr.push({
id: movie.id,
name: movie?.original_name
? movie?.original_name
: movie.original_title,
image: movie.backdrop_path,
genres: movieGenres.slice(0, 3),
});
}
});
};
const movieSlice = createSlice({
name: "movie",
initialState,
extraReducers: (builder) => {
builder.addCase(getGenres.fulfilled, (state, action) => {
// console.log(action.payload);
state.genres = action.payload;
state.genresLoaded = true;
});
builder.addCase(fetchMovies.fulfilled, (state, action) => {
console.log('fetchMovies', action.payload);
state.movies = action.payload;
});
},
});
export default movieSlice.reducer;
chat GPT의 답변은 참고용이다.. 완벽하지 않았다.
개선할 곳을 물어보고 한줄 한줄 어느 부분이 어떻게 수정 되었는지 파악하면서도
이상하거나 이해가 안되는 부분은 몇번이고 질문을 해야했고,
틀린 답변을 내놓는 경우도 많았다.
하지만 계속적으로 질문하면서 많은 부분이 공부가 되었고,
기존 코드에서 비효율적이라고 어렴풋이 느꼈지만 혼자서는 어떻게 더 개선해야할 지 전혀 갈피를 잡을 수 없었던 부분에 대해서는 개선의 방법을 찾을 수 있게 되어 큰 도움이 되었다.