Skip to content

Commit

Permalink
added postSeach
Browse files Browse the repository at this point in the history
  • Loading branch information
ExLuZiVe53 committed Oct 28, 2023
1 parent d62688e commit ac219b7
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 68 deletions.
48 changes: 14 additions & 34 deletions src/pages/SearchPage.jsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,31 @@
import { ReactComponent as IconSearch } from 'assets/images/search.svg';
import ErrorMessage from 'components/ErrorMessage';
import Loader from 'components/Loader';
import { useEffect, useState } from 'react';
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link, useLocation, useSearchParams } from 'react-router-dom';
import { findPostById } from 'services/api';

// (async () => { // -- IIFE (Immediately invoked function expression)
// try {
// setIsLoading(true);
// const postData = await findPostById(query);
import Loader from 'components/Loader';
import ErrorMessage from 'components/ErrorMessage';

import { requestPosts } from 'redux/postsReducer';

// setPosts([postData]);
// } catch (error) {
// setError(error.message);
// } finally {
// setIsLoading(false);
// }
// })()
import { ReactComponent as IconSearch } from 'assets/images/search.svg';

const SearchPage = () => {
// /search?query=56
const [searchParams, setSearchParams] = useSearchParams();
const location = useLocation();
const [posts, setPosts] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);

const posts = useSelector(state => state.postsData.posts);
const isLoading = useSelector(state => state.postsData.isLoading);
const error = useSelector(state => state.postsData.error);
const dispatch = useDispatch();

const query = searchParams.get('query');

useEffect(() => {
if (!query) return;

const fetchAllPosts = async () => {
try {
setIsLoading(true);
const postData = await findPostById(query);

setPosts([postData]);
} catch (error) {
setError(error.message);
} finally {
setIsLoading(false);
}
};

fetchAllPosts();
}, [query]);
dispatch(requestPosts(query));
}, [query, dispatch]);

const handleFormSubmit = event => {
event.preventDefault();
Expand Down
1 change: 0 additions & 1 deletion src/redux/postDetailReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const INITIAL_STATE = {
postDetailsData: null,
isLoading: false,
error: null,
posts: [],
};

const postDetailsSlice = createSlice({
Expand Down
33 changes: 0 additions & 33 deletions src/redux/postReducer.js

This file was deleted.

66 changes: 66 additions & 0 deletions src/redux/postsReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { findPostById } from 'services/api';

// !==============================DAL (Data Accsess Layer)=================
// створюємо асинхрону санку, яка приймає в собі два обов'язкові агрументи:
// 1) Так званий префікс санки, тобто кожна THUNK має мати унікальний префікс
// 2) Асинхрона колбек функція 'async () => {}', дана функція приймає якісь дані (data) та thunkApi

export const requestPosts = createAsyncThunk(
'posts/get',

async (query, thunkApi) => {
try {
// робимо мережевий запит
const searchedPosts = await findPostById(query);
return searchedPosts; //Буде записано в action.payload
} catch (error) {
// після невдалого запиту ми повернемо thunkApi та викличемо спеціальний метод rejectWithVale і передамо об'єкт помилки
return thunkApi.rejectWithValue(error.message);
// rejected - виникне тільки коли ми руками переведемо проміс
}
}
);

// !========================End/ DAL =================================

// створюємо початковий стан state
const INITIAL_STATE = {
posts: null,
isLoading: false,
error: null,
};

// Slice -створюємо новий слайс
const postsSlice = createSlice({
// встановлюємо ім'я слайсу
name: 'posts',
// встановлюємо початковий стан ред'юсера слайсу
initialState: INITIAL_STATE,
// створюємо об'єкт ред'юсерів
// !===========================REDUX BLL===========================
// thunk повертає спеціальні ред'юсери які отримують builder.addCase та назву thank
extraReducers: builder =>
builder
// PENDING - стан очікування запиту
.addCase(requestPosts.pending, (state, action) => {
state.isLoading = true;
state.error = null;
})
// FULFILED - запит пройшов успішно, та повернув дані
.addCase(requestPosts.fulfilled, (state, action) => {
state.isLoading = false;
// в Reducer дані потрапляють тільки через один спосіб -- action.payload
state.posts = [action.payload];
// [action.payload] = запихаємо в масив бо в санку searchedPosts прийде тільки один пост, із-за api, замість об'єкту
})
// REJECTED - виникла помилка під час запису
.addCase(requestPosts.rejected, (state, action) => {
state.isLoading = false;
state.error = action.payload;
}),
// !=====================End/ REDUX BLL===========================
});

// ред'юсер слайсу
export const postsReducer = postsSlice.reducer;
3 changes: 3 additions & 0 deletions src/redux/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { postDetailsReducer } from './postDetailReducer';
import { postsReducer } from './postsReducer';

const postDetailsConfig = {
key: 'postDetails',
Expand All @@ -22,9 +23,11 @@ const postDetailsConfig = {
};

// configureStore приймає об'єкт опцій
// прикріпляємо ред'юсер до стору
export const store = configureStore({
reducer: {
postDetails: persistReducer(postDetailsConfig, postDetailsReducer),
postsData: postsReducer,
},
middleware: getDefaultMiddleware =>
getDefaultMiddleware({
Expand Down

0 comments on commit ac219b7

Please sign in to comment.