2017-05-14 2 views
0

Ich möchte in der Lage sein, die Klasse "aktiv" an/aus für ein einzelnes Element einer Liste umzuschalten. Sagen wir eine Liste von Elementen haben:React - Toggle css Klasse

<ul> 
    <li><a href="#" className="list-item">First</a></li> 
    <li><a href="#" className="list-item">Second</a></li> 
    <li><a href="#" className="list-item">Third</a></li> 
</ul> 

und ich möchte in der Lage sein, Klasse „aktiv“ auf einem zweiten Element auf Klick hinzuzufügen. Ich kann den Zustand dafür nicht benutzen, weil es die Klassen anderer 2 Elemente verändern würde, wenn wir die Bedingung dort hinzufügen, richtig?

Also könnte die Lösung sein, eine Unterkomponente say <ListItem /> zu erstellen, die ihren eigenen Status und eigene Onclick-Methode haben könnte, die nur seine eigene Klasse ändern würde. Wenn wir jedoch die Klasse "aktiv" für andere Elemente beim Klicken entfernen möchten, müsste diese Unterkomponente eine Methode an ein Elternelement senden, um die Klasse von anderen Elementen zu entfernen. Es scheint ziemlich kompliziert für eine einfache Aufgabe (Sie kennen die 10secs-in-jquery-Art).

Hat jemand eine einfachere Lösung dafür?

Es wäre sehr schön, nicht einen weiteren großen npm Modul dafür, document.getElementsByClassName (natürlich) noch Refs verwenden.

+0

, was ist das Problem mit dem Staat hier mit? 'weil es die Klassen anderer 2 Elemente verändern würde 'was meinst du damit? Sie würden nicht alle bei einer Änderung des Staates ändern. und selbst wenn sie das täten, wäre das kein Leistungsproblem. Nicht sicher, was das Problem ist. –

Antwort

2

können Sie den ausgewählten Zustand außerhalb der item Komponente verwalten und es als Stütze passieren.
Ein Event-Handler von onSelect/onClick können die state auslösen und ändern.

const data = [1,2,3,4,5]; 
 

 
class List extends React.Component { 
 
\t constructor(props){ 
 
\t \t \t super(props); 
 
     
 
     this.state = { 
 
     \t selectedItem: 0 
 
     }; 
 
     this.onSelect = this.onSelect.bind(this); 
 
    } 
 
    
 
    onSelect(id){ 
 
    \t this.setState({ 
 
    \t selectedItem: id 
 
    }); 
 
    } 
 
    
 
    render() { 
 
    \t const {selectedItem} = this.state; 
 
    \t return ( 
 
     <ul> 
 
      {data.map((d, index) => { 
 
      \t return <ListItem 
 
         key={index} 
 
         selected={index + 1 == selectedItem} 
 
         value={d} 
 
         id={d} 
 
         onSelect={this.onSelect} 
 
        /> 
 
      })} 
 
      
 
     </ul> 
 
    ) 
 
    } 
 
} 
 

 
const ListItem = (props) => { 
 

 
    const onSelect = (e) => { 
 
    \t props.onSelect(e.target.id); 
 
    } 
 
    
 
    const className = props.selected && "selected"; 
 
    \t 
 
\t return <li className={className} id={props.id} onClick={onSelect}>{props.value}</li> 
 
} 
 

 
ReactDOM.render(<List />, document.getElementById("root"));
ul{ 
 
    list-style: none; 
 
} 
 

 
li{ 
 
    padding: 5px; 
 
    border: 1px solid #ccc; 
 
    cursor: pointer; 
 
} 
 

 
li.selected{ 
 
    background-color: green; 
 
    color: #fff; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>

+0

Danke, das scheint ein guter Ansatz zu sein –

2

Der richtige Weg, um dieses Problem zu nähern wäre eine Zustandsgröße zu haben, die man definiert die derzeit „aktiv“, dh

this.state = { 
    active: "first" // (or "second", "third", null, etc..) 
}; 

Dann Sie eine Inline-if-Anweisung wie so verwenden können:

Beachten Sie, dass ich annehme, dass Sie diese Listenelemente fest codieren möchten - wenn diese Elemente dynamisch generiert werden, ist es einfach, this.state.active als Index/Ref des aktuell ausgewählten Elements zu setzen.

+0

gute Eins! reparierte es –