2016-03-07 3 views
24
class Option extends React.Component { 
    constructor(props) { 
    super(props); 
    this.handleClickOption = this.handleClickOption.bind(this); 
    } 
    handleClickOption() { 
    // some code 
    } 
    render() { 
    return (
     <li onClick={this.handleClickOption}>{this.props.option}</li> 
    ); 
    } 
} 

Io uso eslint-config-airbnb per controllare il codice precedente e mi mostra un messaggio di errore come Component should be written as a pure function.come risolvere il `Componente dovrebbe essere scritto come un errore di` funzione pura in eslint-react?

Quindi, come modificare il componente precedente in pura funzione?

Grazie per il vostro aiuto.

risposta

27

React 0.14 ha introdotto componenti funzione puri.

Questa dovrebbe essere l'opzione preferita per tutti i componenti stateless.

function Option({ onClick, option }) { 
    return (
     <li onClick={onClick}> 
      {option} 
     </li> 
    ); 
} 
+0

C'è una certa durezza nel fatto che il click handler fa parte del componente nella domanda. – flq

+0

La maggior parte delle volte è meglio definire il gestore di clic a un livello superiore. In alternativa, potresti renderlo una funzione separata nello stesso file. –

0

Ho un problema simile. Qualcuno sa come chiamare un puntello componente specifico all'interno della funzione di clic passato.

E.g.

function ElementRow({onClick, element, key}) { 
    return (
    <tr key={key}> 
     <td><a href="#" onClick={onClick}>Delete</a></td> 
     <td> 
     ... 
     <td>{ element.first } { element.last }</td> 
    </tr> 
); 
} 

All'interno della funzione onClick ho bisogno del element.id. Sto cercando una soluzione senza utilizzare bind()

io so come farlo funzionare con React.createClass o extend React.Component ma non scritto come una funzione pura.

Modifica: ho trovato una soluzione ma non sono sicuro che sia un odore di codice. :)

function ElementRow({ onClick, element, key }) { 
    const _onClick = (e) => { 
    onClick(e, element.id); 
    }; 

    return (
    <tr key={key}> 
     <td><a href="#" onClick={_onClick}>Delete</a></td> 
     <td> 
     ... 
     </td> 
     <td>{ element.first } { element.last }</td> 
    </tr> 
); 
} 
+1

In questa istanza potresti anche inline la funzione 'onClick = {(event) => onClick (event, element.id)}'. In alternativa, prendi in considerazione la definizione dell'evento onClick a un livello superiore (ad esempio il componente principale). In futuro, se hai una domanda, per favore inizia una nuova discussione invece di aggiungere una domanda a una esistente. –

+0

hai ragione, la prossima volta inizierò una nuova discussione, non ne ero sicuro. in questo caso onClick viene passato attraverso oggetti di scena da un componente principale. Penso che valga la pena iniziare una nuova discussione con un esempio completo e più descrittivo. – hyde

10

In ES6 si potrebbe fare qualcosa di simile a questo:

const Option = (props) => { 

    handleClickOption() { 
     // some code 
    } 

    return (
     <li onClick={this.handleClickOption}>{this.props.option}</li> 
    ); 
}; 

Option.propTypes = { 
    // validate props 
}; 

export default Options; 
+2

Niente a che vedere con la tua particolare soluzione, ma più come una risposta generale a questo tipo di stile di codifica: non capisco. Perché creare un nuovo 'handleClickOption' ogni volta che si suppone che il componente esegua il rendering, invece di un oggetto prototipo che condividerà tutti lo stesso riferimento di funzione ma utilizzerà un contesto diverso per ogni esecuzione? Sembra gonfio per il motore JS ... – Swivel

+0

per me funziona bene: D voto per questo @John Meyer – Vijay

6

I componenti funzionali apolidi beneficeranno futuro Reagire ottimizzazioni delle prestazioni specifiche a questi componenti. Ecco il modo in cui possiamo scrivere componente come pura funzione:

const App =() => { 
 
    return (
 
    <div> 
 
     <h2 id="heading">Hello ReactJS </h2> 
 
     <header /> 
 
    </div> 
 
); 
 
}; 
 

 
export default App;

Tuttavia, se si vuole scrivere componente in stile ES6, è ancora possibile fare, ma in questo caso l'errore eslint necessità di essere rimosso (se si utilizza eslint). la seguente modifica nel file di .eslintrc

es:

"rules": { 
 
    "react/prefer-stateless-function": "off" 
 
}

Poi qui ES6 componente stile si può scrivere con eslint abilitazione:

import React, { Component } from 'react'; 
 

 
class Home extends Component { 
 
    render() { 
 
    return (
 
     <header className="header"> 
 
     <h1>Home page</h1> 
 
     </header> 
 
    ); 
 
    } 
 
} 
 

 
export default Home;