#reactjs #dictionary #state
Вопрос:
Я пытаюсь использовать setState
для установки данных из a useQuery
с помощью клиента Apollo с помощью OnCompleted
функции, однако, похоже, она не устанавливает данные, и я изо всех сил пытаюсь выяснить, почему.
Кроме того, будет ли мое сопоставление таблиц соответствующим образом обновляться после setState
установки?
console.log
В handleSubmit
функции всегда пусто, и ничего не отображается. Но если я сделаю data.horses
журнал консоли, он будет там.
Вот мой код:
import { useQuery, gql } from "@apollo/client";
import { useState } from "react";
const DataTable = () => {
const GET_HORSES = gql`
query{
horses{
horseCode
horseName
foalingYear
gender
trainer{
trainerCode
}
}
}`;
const [horses, setHorses] = useState([]);
const { data, loading, error} = useQuery(GET_HORSES, {
OnCompleted: (data) => setHorses(data.horses)
});
if (loading) { return "Loading..." };
if (error) { return "Error loading data!"};
if (!data) { return "No data available!"};
const handleSubmit = () => {
var ddSearch = document.getElementById("ddSearch");
var ddSearchVal = ddSearch.value;
if(ddSearchVal === "HorseCode") {
}
console.log(horses);
}
return (
<div className="flex-column">
<div className="Data-search">
<strong>Searching</strong>
<br/>
<select id="ddSearch" >
<option value="HorseCode">Horse Code</option>
<option value="TrainerCode">Trainer Code</option>
<option value="HorseName">Horse Name</option>
</select>
<br/>
<input type="txtSearch" id="search" style={{width: 94}}/>
<br/><br/>
<strong>Foaling Year</strong>
<br />
From:<br/>
<input type="number" id="foalingYearMin" min="2000" max="2010" style={{width: 94}} /><br/>
To:<br/>
<input type="number" id="foalingYearMax" min="2000" max="2010" style={{width: 94}} />
<br/><br/>
<strong>Gender:</strong><br/>
<select id="ddGender" style={{width: 94}}>
<option value="g">g</option>
<option value="f">f</option>
<option value="c">c</option>
</select>
<br/><br/>
<button type="button" style={{width: 94}} onClick={() => handleSubmit()}>Search</button>
<br/>
<button type="button" style={{width: 94}}>Reset</button>
</div>
<table className="Data-table">
<thead>
<tr>
<th>Horse Code</th>
<th>Horse Name</th>
<th>Foaling Year</th>
<th>Gender</th>
<th>Trainer Code</th>
</tr>
</thead>
<tbody>
{horses.map((horse) => (
<tr key={horse.horseCode}>
<td>{horse.horseCode}</td>
<td>{horse.horseName}</td>
<td>{horse.foalingYear}</td>
<td>{horse.gender}</td>
<td>{horse.trainer.trainerCode}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default DataTable;
Я также буду использовать фильтрацию по этому массиву с помощью ввода текстового поиска
Комментарии:
1. Почему бы просто не использовать
data
то, что вы разрушаетеuseQuery
?2. Я хочу добавить фильтрацию и т. Д., Поэтому мне понадобится, чтобы он находился в состоянии, которое я предполагаю, чтобы установить его и отобразить в представлении?
3. @ZackAntonyBucci В таком случае вам нужно хранить фильтры, а не сами данные?
4. Я фильтрую его из текстового ввода, так смогу ли я все еще получить текстовый ввод во время фильтрации? Текст может/изменится (см. Ввод txtSearch)
Ответ №1:
Это onCompleted
не OnCompleted
так — вот почему ваше состояние остается неизменным, даже когда data
обновляется результатами.
Таблица должна обновляться сама по себе, как только React фиксирует изменения, запланированные setHorses
вызовом (для простоты мы можем видеть, как только setHorses
вызывается).
Для целей фильтрации (упомянутых в комментариях) на самом деле не требуется просматривать данные в локальном состоянии. Вы можете отфильтровать результаты, используя filter
их перед сопоставлением с компонентами реакции, или использовать useMemo
hook для предотвращения ненужных итераций.
Комментарии:
1. Глупая я…. Я также использовал useEffect (), чтобы установить его: useEffect(() => { if(данные и данные.лошади) { setHorses(данные.лошади); } }, [данные]); и это также сработало. Спасибо.