2015-10-23 15 views
8

ES7 introduce il concetto di static definizioni di proprietà e metodo. Insieme con un transpiler ES7-grado, questi can be used in React per specificare validatori e le impostazioni predefinite per props, in questo modo:Sovrascrivi/estendi le proprietà statiche sulle classi ES7 in React.js

export default class ComponentOne extends React.Component { 
    static propTypes = { 
     foo: React.PropTypes.string 
    } 
    static defaultProps = { 
     foo: 'bar' 
    } 
    // ... 
} 

Questo è super a portata di mano, ma diventa difficile quando sottoclassi entrano in gioco. Ad esempio, dire il seguente modulo viene aggiunto lo stesso codice di base come ComponentOne sopra:

export default class ComponentTwo extends ComponentOne { 
    static propTypes = { 
     baz: React.PropTypes.number 
    } 
    static defaultProps = { 
     baz: 42 
    } 
    // ... 
} 

mi piacerebbe ComponentTwo a "ereditare" i validatori di proprietà e le impostazioni predefinite della sua superclasse, ComponentOne. Invece, propTypes e su ComponentTwo shadow quelli su ComponentOne e React eliminano quelli definiti su ComponentOne.

Dal super è un riferimento al prototipo della classe corrente e static si suppone che valori di riferimento appeso direttamente fuori il prototipo, ho pensato che questo potrebbe funzionare:

import _ from 'lodash'; 
export default class ComponentTwo extends ComponentOne { 
    static propTypes = _.merge(super.propTypes, { 
     baz: React.PropTypes.number 
    }); 
} 

Tuttavia, questo genera un errore, presumibilmente da Babele: Parsing error: 'super' outside of function or class.

Questo funziona, ma non è molto portatile:

export default class ComponentTwo extends ComponentOne { 
    static propTypes = Object.assign({ 
     baz: React.PropTypes.number 
    }, ComponentOne.propTypes); 
} 

Ci sono altri modi per fare questo in modo più pulito/reusably?

+0

si prega di essere a conoscenza delle avvertenze quando ereditare classi con proprietà statiche: "Se stai eredita da una classe di proprietà statiche poi vengono ereditate da esso tramite' __proto__', questo è ampiamente supportato ma è possibile che si verifichino problemi con i browser più vecchi. NOTA: '__proto__' non è supportato su IE <= 10, quindi le proprietà statiche non verranno ereditate." fonte: https://babeljs.io/docs/advanced/caveats/ – Raspo

+0

Hai provato a fare l'unione 'super.propTypes' nel costruttore? –

+0

@Mat Non l'ho fatto, ma dato che 'props' entrano nel costruttore con valori predefiniti già impostati, immagino che sarebbe troppo tardi. – ericsoco

risposta

0

Stranamente, utilizzando super funziona per metodi statici. Penso che dovrebbe funzionare anche per le proprietà statiche. Per me, quindi, ci si sente più naturale per utilizzare il nome della classe Super direttamente:

export default class ComponentTwo extends ComponentOne { 
    static propTypes = _.merge({}, ComponentOne.propTypes, { 
    baz: React.PropTypes.number 
    }); 
} 

Ma, per usare super, una soluzione che posso pensare è utilizzando un metodo statico per inizializzare la proprietà, che purtroppo avrebbe di essere chiamato manualmente:

class ComponentTwo extends ComponentOne { 
    static _init() { 
    this.propTypes = _.merge({}, super.propTypes, { 
     baz: React.PropTypes.number 
    }); 
    } 
} 
ComponentTwo._init(); 
+0

Non è solo un refactoring del suggerimento alla fine del mio post? Usando 'lodash' invece di' Object.assign'? Il mio problema con questo è esplicitamente riferimento a 'ComponentOne' invece di essere in grado di fare riferimento alla classe" super ". Non è un grosso problema dal momento che devi fare riferimento all'istruzione 'extends', ma non ideale. – ericsoco

+0

Sì, è proprio così, ma con il modo giusto di usare _merge_. –

+0

Aggiunta anche un'altra alternativa, che ritengo sia peggiore. –

Problemi correlati