Порядок использования и состояние использования

#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(данные.лошади); } }, [данные]); и это также сработало. Спасибо.