2016-07-07 27 views
5

Sono nuovo di ES6. Mi sono un po 'confuso su diversi modi di scrivere un componente React. Ho iniziato con un "React.createClass" quindi spostato in "estende React.Component" con la sintassi delle classi ES6.Refactor a Componente React dalla funzione alla classe ES6

seguito Redux esercitazione ora vedo che definiscono i componenti in questo modo

import React, { PropTypes } from 'react' 

const Todo = ({ onClick, completed, text }) => (
    <li onClick={onClick} style={{ textDecoration: completed ? 'line-through' : 'none' }} > 
     {text} 
    </li> 
) 

Todo.propTypes = { 
    onClick: PropTypes.func.isRequired, 
    completed: PropTypes.bool.isRequired, 
    text: PropTypes.string.isRequired 
} 

export default Todo 

Come posso refactoring questa "funzione" si muove a una classe ES6 che si estende React.component? Immagino che il ritorno JSX sia il metodo render(), non è vero? E gli argomenti di testo onClick, completati?

Grazie

risposta

3

Per il componente in realtà è meglio renderlo una funzione pura, piuttosto che una classe ES6, perché può eseguire il rendering come una funzione di esso è props e non mantiene lo stato. È comunque possibile utilizzare la sintassi ES6 (esportazione, funzioni freccia, ecc.).

Facebook's explanation:. "In un mondo ideale, la maggior parte dei componenti sarebbe funzioni apolidi perché in futuro ci sarà anche in grado di fare ottimizzazione delle prestazioni specifiche per questi componenti, evitando inutili controlli e le allocazioni di memoria Questa è la raccomandata modello, quando possibile. "

import { PropTypes } from 'react' 

function Todo = (props) => (
    <li onClick={props.onClick} style={{ textDecoration: props.completed ? 'line-through' : 'none' }} > 
     {props.text} 
    </li> 
) 

Todo.propTypes = { 
    onClick: PropTypes.func.isRequired, 
    completed: PropTypes.bool.isRequired, 
    text: PropTypes.string.isRequired 
} 

export default Todo 
+1

Questo è esattamente ciò che dovrebbe essere fatto. Solo perché * puoi * scrivere un componente come una classe ES6 non significa che tutte le componenti * dovrebbero * essere classi. –

+0

Sto sostenendo la tua soluzione. Non sapevo che non è possibile utilizzare PropTypes.shape per gli oggetti di scena nel componente. –

+0

Evita di rispondere alle domande con: "Il modo migliore per fare X è come l'ABC, quindi ecco l'ABC" - Voleva una versione ES6 della versione pura della funzione, NON una ripetizione del problema esatto a cui si riferiva. – holografix

4

La sintassi equivalente ES6 sarebbe:

import React, { Component, PropTypes } from 'react' 

class Todo extends Component { 
    render() { 
    const { onClick, completed, text } = this.props 

    return (
     <li onClick={onClick} style={{ textDecoration: completed ? 'line-through' : 'none' }} > 
      {text} 
     </li> 
    ) 
    } 
} 
Todo.propTypes = { 
    onClick: PropTypes.func.isRequired, 
    completed: PropTypes.bool.isRequired, 
    text: PropTypes.string.isRequired 
} 

export default Todo 

Se si utilizza babel al transpile il codice e si ha la class properties transform allora si può fare quanto segue:

import React, { Component, PropTypes } from 'react' 

class Todo extends Component { 
    static propTypes = { 
    onClick: PropTypes.func.isRequired, 
    completed: PropTypes.bool.isRequired, 
    text: PropTypes.string.isRequired 
    } 

    render() { 
    const { onClick, completed, text } = this.props 

    return (
     <li onClick={onClick} style={{ textDecoration: completed ? 'line-through' : 'none' }} > 
      {text} 
     </li> 
    ) 
    } 
} 

export default Todo 

Giusto per essere chiari questo secondo esempio ca Non può essere considerato "standard ES6", tuttavia trovo le proprietà statiche molto più pulite, quindi ho pensato che valesse la pena mostrare anche questo approccio.

+2

L'OP ha richiesto una classe ES6, la risposta è un errore di sintassi. – Bergi