Каков наилучший масштабируемый способ реализации ContextProvider для выборки и фильтрации данных?

Я работал над проектом, который требует получения большого количества данных и предоставляет несколько способов фильтрации/поиска данных, и я думал о сохранении фильтрации на стороне сервера, учитывая, что буду использовать нумерацию страниц.

Недавно я начал использовать React Context и попробовал подход, который не сработал.

вот специальный хук React, который я использую для получения данных

import { useState, useEffect } from 'react';

const useFetch = (url, url_params) => {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    const [refresh, setRefresh] = useState(0);

    if (url_params) {
        url = url + '?' + url_params.toString();
    }

    const refreshData = () => {
        setRefresh((prev) => prev + 1);
    }

    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                const result = await response.json();
                setData(result);
            } catch (error) {
                setError(error);
            } finally {
                setLoading(false);
            }
        };

        fetchData();
    }, [refresh, url]);

    return { data, loading, error, refreshData };
};

export default useFetch;

и вот contextProvider:

import { createContext, useState, useEffect, useContext } from "react";
import { listing_url } from "../../Hooks/api_endpoints";
import useFetch from "../../Hooks/useFetch";
import { useSearchParams } from "react-router-dom";

export const HouseContext = createContext();

export const HouseProvider = ({ children }) => {
    const [selectedHouse, setSelectedHouse] = useState(null);
    // I have tried multiple approaches for searchParams (one is search params and the other is testParams
    const [searchParams, setSearchparams] = useState({
        address__icontains: '',
        apartment_no__icontains: '',
        block__iexact: '',
        currency__iexact: '',
        floor__iexact: '',
        gross__gte: '',
        gross__lte: '',
        net__gte: '',
        net__lte: '',
        num_of_floors__iexact: '',
        num_of_rooms__iexact: '',
        owner__icontains: '',
        owner_phone_num__icontains: '',
        price__gte: '',
        price__lte: '',
        status__iexact: '',
        view__icontains: '',
    });

    // second attempt at implementing searchParams
    const testParams = new URLSearchParams({
        address__icontains: '',
        apartment_no__icontains: '',
        block__iexact: '',
        currency__iexact: '',
        floor__iexact: '',
        gross__gte: '',
        gross__lte: '',
        net__gte: '',
        net__lte: '',
        num_of_floors__iexact: '',
        num_of_rooms__iexact: '',
        owner__icontains: '',
        owner_phone_num__icontains: '',
        price__gte: '',
        price__lte: '',
        status__iexact: '',
        view__icontains: '',
    });

    const { data: houses, error: housesError, loading: housesLoading, refreshData: houseRefresh } = useFetch(listing_url, testParams);

    const createHouse = async (house) => {

        const newHouse = await fetch(listing_url, {
            method: "POST",
            body: JSON.stringify(houseData),
        });
        setHouses([...houses, newHouse]);
    }

    // useEffect(() => {
    //     console.info("houses were updated")
    //     console.info(' search params were updated')
    // }, [houses, testParams])

    const updateSearchParams = (key, value) => {
        console.info("firing updateSearchParams")
        houseRefresh();
        testParams.set(key, value);
    }

    return (
        <HouseContext.Provider value = {{ houses, selectedHouse, housesError, housesLoading, setSelectedHouse, createHouse, testParams, updateSearchParams }}>
            {children}
        </HouseContext.Provider>
    )
}

и вот как я пытался использовать параметры фильтрации на своей домашней странице:

import { HouseContext } from '../../Context/House/House';

// .....

export default function Home() {
// .....

    const { testParams, updateSearchParams } = useContext(HouseContext)

    // ......
    return (
          // ......

          <div className='flex'>
            <span className='text-sm/3 my-auto pr-2 dark:text-white'>floor</span>
            <input type='number' placeholder='floor' min = {0} onChange = {(e) => { updateSearchParams('floor__iexact', e.target.value) }} className='w-14 rounded border border-black' />
          </div>
    // .....

теперь у меня есть 2 вопроса по этому поводу:

  1. почему список houses не обновляется, когда updateSearchParams срабатывает?
  2. действителен ли этот подход или мне следует просто прибегнуть к выборке данных и последующей фильтрации на стороне клиента? и если да, то как мне это сделать после добавления нумерации страниц?

Знаете ли вы, где в цепочке updateSearchParams происходит сбой? Извлечение никогда больше не срабатывает? Или мы неправильно обновляем testParams? или это что-то еще

justnut 10.08.2024 06:27

@justnut, насколько мне известно, testParams обновляется, и useFetch внутри contextProvider снова вызывается, но список houses не обновляется

Abdullah Shekfeh 10.08.2024 17:50

Откуда взялась функция setHouses, используемая в createHouse?

justnut 10.08.2024 21:41

@justnut ох, жаль, это было из предыдущей итерации

Abdullah Shekfeh 12.08.2024 02:42
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
4
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я считаю, что проблема, с которой вы здесь столкнулись, вызвана тем, что ничто не вызывает повторный рендеринг, поэтому вы не видите никаких изменений в домах.
Я считаю, что самый простой способ исправить это:

const [testParams, setTestParams] = useState(new URLSearchParams({ ... rest of the tings })

Затем обновите updateSearchParams, чтобы вместо настройки testParams, которую вы делали, выполнялось следующее:

setTestParams(prev => {
    const newParam = new URLSearchParams(prev);
    newParam.set(key, value);
    return newParam;
});

Это изменение теперь должно привести к тому, что React запустит повторный рендеринг и, надеюсь, покажет вам обновленные дома.
Я также был бы осторожен с onChange, который вы сейчас делаете, это может вызвать некоторые проблемы и отправку большого количества запросов.

Другие вопросы по теме