React - menu po najechaniu na wyrenderowanych elementach

React - menu po najechaniu na wyrenderowanych elementach
O2
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:21
0

Cześć. To mój pierwszy wpis i pilnie potrzebuję pomocy. Robię stronkę w React która z API ciągnie dane i na podstawie ich renderuje listę. W każdym elemencie listy jest img po najechaniu na które dla ul zmienia się klasa i staje się widoczna, czyli wyskakuje małe menu. Niestety nie wiem jak zrobić, by na jednym konkretnym wyrenderowanym i najechanym myszką elemencie to menu wyskakiwało. Teraz niestety wyskakuje na wszystkich na raz co jest niezamierzone. Staram się to jakoś uzależnić od id, ale brak mi już pomysłów.```

Kopiuj
import React, { Component } from 'react';
import menu from '../Images/menu.png';



class Container extends Component {
    constructor(props) {
        super(props);
        this.menuEnter = this.menuEnter.bind(this);
    }

    state = {
        servers: [],
        serverId: [],
        serverName: '',
        serverStatus: '',
        isVisible: false,
    };


    componentDidMount() {
        fetch('http://localhost:4454/servers')
            .then(response => response.json())
            // .then(data => console.log(data))

            .then(data => {
                this.setState ({
                    servers: data,
                    serverId: data.id,
                    serverName: data.name,
                    serverStatus: data.status,
                    isVisible: false
                }, console.log(this.state.servers))
            })
            .catch(error => console.log(error))
    }

    componentDidUpdate() {
        console.log(this.state.servers);
    }


    menuEnter = () => {
        console.log('Działa');
       this.setState(prevState => ({ isVisible: !prevState.isVisible }));
    };





    render() {

        const {isVisible} = this.state;
        return(
            <div className="prostok-t-1">
                <section className='grupa-1'>
                    <div className='title'>
                        <input className='form' type="text" 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.servers.map((server) => {
console.log(server);


                            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)} className='menu' src={menu} alt="menu"/>
                                        <ul className={`box ${isVisible ? "menuEnter" : " submenu"}`}>
                                            <li>Turn on</li>
                                            <li>Turn off</li>
                                            <li>Reboot</li>
                                        </ul>
                                    </div>
                                )

                            })}
                        </div>
                    </div>
                </section>
            </div>
        )
    }
}

export default Container;
SZ
  • Rejestracja:prawie 11 lat
  • Ostatnio:3 minuty
  • Postów:1501
0

No bo jak zmieniasz state to klasę menuEnter dostają wszystkie ul. Nie wiem czy zadziała bo z pamięci ciężko ale może zrób tak.

Kopiuj
 menuEnter = e => {  //gdzie e to najechany element
        
      
        tu  ustawiasz klasy dla elementu ul // ul to jest kolejny element po e
    };

<img onMouseOver={this.menuEnter)} className='menu' src={menu} alt="menu"/>

podobnie trzeba wrócić do poprzedniego stanu, Czyli chyba onmouseout.
I ten state byłby raczej nie potrzebny

edytowany 3x, ostatnio: szydlak
O2
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:21
0

I tu gdzie w zależności od state to mam ifem lecieć? Zgłupiałem już kompletnie przez to

SZ
  • Rejestracja:prawie 11 lat
  • Ostatnio:3 minuty
  • Postów:1501
0

Moim zdaniem state do tego się nie nadaje. Bo masz wiele menu a jeden state. I zmiana state spowoduje, że zmiany zajdą dla każdego menu a nie tylko dla najechanego

O2
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:21
0

Innych pomysłów nie mam. Myślę, że trzeba to jakoś uzależnić od server.id, czyli id pojedynczego elementu, ale nie mam pomysłu jak

SZ
  • Rejestracja:prawie 11 lat
  • Ostatnio:3 minuty
  • Postów:1501
0

Ta część podejrzanie wygląda

Kopiuj
servers: data,
serverId: data.id,
serverName: data.name,

Skoro data jest tablicą to data.id is undefined

O2
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:21
0

Tablica obiektów. Listę i ich statusy renderuje tak jak powinno. To co zaznaczyłeś w zasadzie można usunąć nawet bo jest nieużywane poza pierwszą pozycją

edytowany 3x, ostatnio: Ovonel265
SZ
Jak wrzucisz na sandboxa minimalna ilość działającego kodu spróbuje pomóc
SZ
  • Rejestracja:prawie 11 lat
  • Ostatnio:3 minuty
  • Postów:1501
0

Nie komplikuj sobie z żadnym ID ani statem. Odczytaj najechany element (e) w metodzie zdarzenia. Weź kolejny (nextSibling) i dodaj mu klasę

O2
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:21
0
szydlak napisał(a):

Nie komplikuj sobie z żadnym ID ani statem. Odczytaj najechany element (e) w metodzie zdarzenia. Weź kolejny (nextSibling) i dodaj mu klasę

Kombinowałem takie coś i się krzaczyło wszystko. Czekam na pomysły ;p Wieczorem do tego pewnie wrócę ;)

O2
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:21
0
szydlak napisał(a):

Nie komplikuj sobie z żadnym ID ani statem. Odczytaj najechany element (e) w metodzie zdarzenia. Weź kolejny (nextSibling) i dodaj mu klasę

Coś takiego miałeś na myśli? Próbowałem, krzaczy się i wywala, że nie może odczytać setState. Cannot read property 'setState' of undefined.

Kopiuj

```    menuEnter = (e) => {
        console.log('Działa');
       e.nextSibling.setState(prevState => ({ isVisible: !prevState.isVisible }));
    };
SZ
  • Rejestracja:prawie 11 lat
  • Ostatnio:3 minuty
  • Postów:1501
0

Nie. W ogole wywal state.

Kopiuj
menuEnter = (e) => {
      
       let submenu= e.domEvent.target.nextSibling;
//i teraz manipulujesz klasami
   };
edytowany 3x, ostatnio: szydlak
O2
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:21
0
szydlak napisał(a):

Nie. W ogole wywal state. Nextsibling.addClass

W React tego tak nie zrobisz właśnie. Kopie internet może coś wynajdę.

SZ
faktycznie jest to problematyczne.
SZ
Ale działa tak: w zdarzeniu e.domEvent.target.nextSibling.className="klasa pokazująca submenu"

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.