2015-09-18 5 views
168

Sto imparando Redux con React e sono incappato in questo codice. Non sono sicuro se sia lo Redux specifico o no, ma ho visto il seguente frammento di codice in uno degli esempi.Qual è il '@' (simbolo) nel decoratore Redux @ connect?

@connect((state) => { 
    return { 
    key: state.a.b 
    }; 
}) 

Mentre la funzionalità di connect è piuttosto semplice, ma non capisco il @ prima connect. Non è nemmeno un operatore JavaScript se non sbaglio.

Qualcuno può spiegare per favore cos'è questo e perché viene utilizzato?

Aggiornamento:

Si tratta infatti di una parte del react-redux che viene utilizzato per collega un componente Reagire a un negozio di Redux.

+6

Non ho dimestichezza con Redux, ma sembra un decoratore. https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841 – Lee

+1

Mi piace come in questo nuovo mondo JavaScript tu stia fissando il codice per metà del tempo e pensando "quale parte della sintassi del linguaggio è questa? " –

+3

Lol, sono molto in profondità e ora lo sono. Ma all'epoca non sapevo che la sintassi del decoratore non avesse nulla a che fare con il redux. È solo JavaScript. Felice di vedere questa domanda sta aiutando molte persone come me. :) –

risposta

299

Il @ simbolo è in realtà un'espressione JavaScript currently proposed to signify decorators:

decoratori permettono di annotare e modificare le classi e le proprietà in fase di progettazione.

Ecco un esempio di impostazione Redux senza e con un decoratore:

Senza decoratore

import React from 'react'; 
import * as actionCreators from './actionCreators'; 
import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 

function mapStateToProps(state) { 
    return { todos: state.todos }; 
} 

function mapDispatchToProps(dispatch) { 
    return { actions: bindActionCreators(actionCreators, dispatch) }; 
} 

class MyApp extends React.Component { 
    // ...define your main app here 
} 

export default connect(mapStateToProps, mapDispatchToProps)(MyApp); 

Utilizzando un decoratore

import React from 'react'; 
import * as actionCreators from './actionCreators'; 
import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 

function mapStateToProps(state) { 
    return { todos: state.todos }; 
} 

function mapDispatchToProps(dispatch) { 
    return { actions: bindActionCreators(actionCreators, dispatch) }; 
} 

@connect(mapStateToProps, mapDispatchToProps) 
export default class MyApp extends React.Component { 
    // ...define your main app here 
} 

Entrambi gli esempi sopra sono equivalenti, è solo un ma di preferenza. Inoltre, la sintassi del decoratore non è ancora incorporata in un runtime Javascript, ed è ancora sperimentale e soggetta a modifiche. Se si desidera utilizzarlo, è disponibile utilizzando Babel.

+34

questo è fantastico –

+1

Uno può anche essere più conciso con la sintassi ES6. @connect ( state => {{return todos: state.todos};} , spedizione => {{return azioni: bindActionCreators (actionCreators, della spedizione)};} ) – LessQuesar

+10

Se si vuole veramente per essere concisi è possibile utilizzare i ritorni impliciti in ES6. Dipende da quanto vuoi essere esplicito. '@connect (state => ({todos: state.todos}), dispatch => ({actions: bindActionCreators (actionCreators, dispatch)}))' –

22

Molto importante!

Questi puntelli sono chiamati oggetti di scena dello stato e sono diversi dai normali oggetti di scena, ogni modifica alle vostre puntelli stato del componente attiverà la componente metodo Render ancora e ancora, anche se non si utilizzano questi puntelli così per motivi di prestazioni prova a legare al tuo componente solo gli oggetti di scena di cui hai bisogno all'interno del tuo componente e se usi un oggetto ausiliare leghi solo questi oggetti di scena.

esempio: permette di dire dentro il componente è necessario solo due oggetti di scena:

  1. l'ultimo messaggio
  2. il nome utente

Non fare questo

@connect(state => ({ 
    user: state.user, 
    messages: state.messages 
})) 

fare questo

@connect(state => ({ 
    user_name: state.user.name, 
    last_message: state.messages[state.messages.length-1] 
})) 
+6

o utilizzare selettori come reselect o fastmemoize –

+0

https://survivejs.com/react/appendices/understanding-decorators/ e https://www.sitepoint.com/javascript-decorators-what-they-are/ – zloctb