React - menu po najechaniu na wyrenderowanych elementach

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.```

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;
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.

 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

0

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

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

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

0

Ta część podejrzanie wygląda

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

Skoro data jest tablicą to data.id is undefined

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ą

0

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

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ę ;)

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.


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

Nie. W ogole wywal state.

menuEnter = (e) => {
      
       let submenu= e.domEvent.target.nextSibling;
//i teraz manipulujesz klasami
   };
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ę.

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