Я работал над проектом, который требует получения большого количества данных и предоставляет несколько способов фильтрации/поиска данных, и я думал о сохранении фильтрации на стороне сервера, учитывая, что буду использовать нумерацию страниц.
Недавно я начал использовать 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 вопроса по этому поводу:
houses
не обновляется, когда updateSearchParams
срабатывает?@justnut, насколько мне известно, testParams обновляется, и useFetch внутри contextProvider снова вызывается, но список houses
не обновляется
Откуда взялась функция setHouses, используемая в createHouse?
@justnut ох, жаль, это было из предыдущей итерации
Я считаю, что проблема, с которой вы здесь столкнулись, вызвана тем, что ничто не вызывает повторный рендеринг, поэтому вы не видите никаких изменений в домах.
Я считаю, что самый простой способ исправить это:
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, который вы сейчас делаете, это может вызвать некоторые проблемы и отправку большого количества запросов.
Знаете ли вы, где в цепочке updateSearchParams происходит сбой? Извлечение никогда больше не срабатывает? Или мы неправильно обновляем testParams? или это что-то еще