"Odfiltrowywanie" wyszukiwarki - React

0

Udało mi się zrobić w końcu wyszukiwarkę dla renderowanych elementów, ale mam problem, bo po skasowaniu wpisu w inpucie wszystko zostaje w state i jakby nie odfiltrowuje. Renderuje na podstawie servers, a nie filteredServers. A jak zmienie na filtered servers to renderuje dopiero po wpisaniu czegoś do inputa ;p I tak źle i tak nie dobrze xD Ktoś coś doradzi jak poprawić tą funkcję?

Wycinki kodu:


```state = {
        servers: [],
        activeMenu: [],
        filteredServers: []
    };


    componentDidMount() {
        fetch('http://localhost:4454/servers')
            .then(response => response.json())
            .then(data => {
                this.setState ({
                    servers: data,
                    activeMenu: [],
                    filteredServers: []
                })
            })
            .catch(error => console.log(error))





    filterServers = (event) => {
        const originalServersList = this.state.servers || [];
        const filteredServers = originalServersList.filter(item => item.name.toLowerCase().search(event.target.value.toLowerCase()) !== -1);
        this.setState({servers: filteredServers})
    };
0

this.setState({filteredServers: filteredServers}). W tej chwili zapisujesz do state servers przefiltrowane serwery, które na następną zmianę inputa filtrującego pobierasz już pomniejszone o poprzednie filtrowania. Tak naprawdę nie potrzebujesz state trzymającego wszystkie serwery, zrób z tego po prostu pole klasy, a statem będzie tylko filteredServers.

0
Chramar napisał(a):

this.setState({filteredServers: filteredServers}). W tej chwili zapisujesz do state servers przefiltrowane serwery, które na następną zmianę inputa filtrującego pobierasz już pomniejszone o poprzednie filtrowania.

To wiem o o tym napisałem, ale taka zmiana nie naprawia tego tak jak bym chciał bo renderowane jest i tak na podstawie servers i właśnie nie wiem jak to naprawić, by przy kasowaniu wpisu wracało do stanu poczatkowego, a nie przefiltrowanego.


```<input onInput={this.filterServers} className='form' type="search" placeholder='Search'/>
0

Prosto - zrób tak, jak mówię i renderuj na podstawie filteredServers. W momencie wyczyszczenia pola "wyfiltruje" zero serwerów, więc dostaniesz de facto całą listę.

0
Chramar napisał(a):

Prosto - zrób tak, jak mówię i renderuj na podstawie filteredServers. W momencie wyczyszczenia pola "wyfiltruje" zero serwerów, więc dostaniesz de facto całą listę.

Chodzi Ci o coś takiego? Próbowałem. Też nie do końca dobrze, bo na początku po załadowaniu wyświetla pustą listę i pokazuje się coś dopiero po wpisaniu.


class Container extends Component {

state = {
    servers: [],
    activeMenu: [],
    filteredServers: []
};


componentDidMount() {
    fetch('http://localhost:4454/servers')
        .then(response => response.json())
        .then(data => {
            this.setState ({
                servers: data,
                activeMenu: [],
                filteredServers: []
            })
        })
        .catch(error => console.log(error))
    
}


menuEnter = (serverId) => {
   this.setState({activeMenu: serverId});
};

menuExit = (serverId) => {
    this.setState({activeMenu: !serverId});
};


filterServers = (event) => {
    const originalServersList = this.state.servers || [];
    const filteredServers = originalServersList.filter(item => item.name.toLowerCase().search(event.target.value.toLowerCase()) !== -1);
    this.setState({filteredServers: filteredServers})
};

turnOn = () => {
    console.log('działa')
};


render() {

    return(
        <div className="prostok-t-1">
            <section className='grupa-1'>
                <div className='title'>
                    <input onInput={this.filterServers} className='form' type="search" placeholder='Search'/>
                    <h2 className='servers'>Servers</h2>
                    <h3 className='number-of-elements-16'>Numbers of elements: 16</h3>
                </div>
                <div className='prostok-t-4'>
                    <div className='place'>
                        <div className="name">
                            <h3>Name</h3>
                        </div>
                        <div className="condition">
                            <h3>Status</h3>
                        </div>
                    </div>

                    <div>{this.state.filteredServers.map((server) => {
                        if (server.name.length > 0) {
                            return (
                                <div className="server" key={server.id}>
                                    <p className="area">{server.name}</p>
                                    <p className="status">{server.status}</p>
                                    <img onMouseOver={() => this.menuEnter(server.id)}
                                         onClick={() => this.menuExit(server.id)} className='menu' src={menu}
                                         alt="menu"/>
                                    <ul className={classNames({
                                        submenu: true,
                                        active: server.id === this.state.activeMenu
                                    })}>
                                        <li onClick={this.turnOn}>Turn on</li>
                                        <li>Turn off</li>
                                        <li>Reboot</li>
                                    </ul>
                                </div>
                            )
                        }
                        return (
                            <p>No results!</p>
                        )
                        })}
                    </div>
                </div>
            </section>
        </div>
    )
}

}

export default Container;

0

Też nie do końca dobrze, bo na początku po załadowaniu wyświetla pustą listę i pokazuje się coś dopiero po wpisaniu.

Musisz w componentDidMount() do filteredServers też przekazać data, bo inaczej jest puste na samym początku, stąd ten problem

0
Chramar napisał(a):

Też nie do końca dobrze, bo na początku po załadowaniu wyświetla pustą listę i pokazuje się coś dopiero po wpisaniu.

Musisz w componentDidMount() do filteredServers też przekazać data, bo inaczej jest puste na samym początku, stąd ten problem

Faktycznie. Nie zauważyłem tego. Wielkie dzięki :) Mam jeszcze pytanie. Bo teraz będę sobie robił zmianę Statusu, PUTem i nie do końca wiem jak robić takie zapytania. O ile dla Get sporo można znaleźć materiałów to inne metody są w zasadzie wspomniane, że istnieją. Jak takie coś ma wyglądać dla czegoś takiego? Dopiero się uczę.
interface Server {
id: number;
name: string;
status: 'ONLINE' | 'OFFLINE' | 'REBOOTING';
}

Coś w tym stylu muszę stworzyć? Nie do końca rozumiem, jak mają inne zapytania wyglądać.


```async updateItem(item) {
    console.log("ItemService.updateItem():");
    console.log(item);
    return fetch(item.link, {
      method: "PUT",
      mode: "cors",
      headers: {
            "Content-Type": "application/json"
          },
      body: JSON.stringify(item)
    })
      .then(response => {
        if (!response.ok) {
          this.handleResponseError(response);
        }
        return response.json();
      })
      .catch(error => {
        this.handleError(error);
      });
  }

1 użytkowników online, w tym zalogowanych: 0, gości: 1