2015-10-01 13 views
25

Ho più componenti che devono tutti fare la stessa cosa. (Una semplice funzione che esegue il mapping sui componenti figlio e fa qualcosa a ciascuno). Al momento sto definendo questo metodo in ognuno dei componenti. Ma voglio solo definirlo una volta.Modo corretto per condividere le funzioni tra i componenti in React

Potrei definirlo nel componente di livello superiore e quindi farlo passare come sostegno. Ma non sembra giusto. È più una funzione di libreria che un oggetto di scena. (Mi sembra).

Qual è il modo corretto di farlo?

risposta

11

Se si utilizza qualcosa come browserify allora si può avere un file esterno i.e util.js che esporta alcune funzioni di utilità.

var doSomething = function(num) { 
return num + 1; 
} 

exports.doSomething = doSomething; 

Poi richiedono come necessario

var doSomething = require('./util.js').doSomething; 
+8

Cosa si dovrebbe fare se queste funzioni modificano lo stato? – aks

+0

@AnkitSinghaniya Dipende, cosa stai utilizzando per gestire lo stato front-end della tua app? – deowk

+1

Sto usando gli stati di reazione. – aks

3

Sembra una funzione di utilità, in tal caso perché non mettere in un modulo separato utilità statico?

caso contrario, se si utilizza un transpiler come Babel si può fare uso di metodi statici di ES7:

class MyComponent extends React.Component { 
    static someMethod() { ... 

Oppure, se si utilizza React.createClass è possibile utilizzare l'oggetto statics:

var MyComponent = React.createClass({ 
    statics: { 
    customMethod: function(foo) { 
     return foo === 'bar'; 
    } 
    } 

Tuttavia non consiglio queste opzioni, non ha senso includere un componente per un metodo di utilità.

Inoltre non si dovrebbe passare un metodo a tutti i componenti come un supporto, ma li accoppierà strettamente e renderà il refactoring più doloroso. Raccomando un semplice modulo di utilità vecchio.

L'altra opzione è utilizzare un mixin per estendere la classe, ma io non lo consiglio poiché non è possibile farlo in es6 + (e in questo caso non vedo il vantaggio).

+0

Le informazioni sui mix sono utili. In questo caso, desidero utilizzare la funzione in modo condizionale anziché che qualcosa avvenga automaticamente durante un evento del ciclo di vita. Così. Come dici tu, una semplice vecchia funzione di utilità è la strada da percorrere. –

+0

Nota: '' React.createClass'' è deprecato da React 15.5.0. create-react-app suggerisce invece l'uso del modulo npm '' create-react-class''. –

2

Non dovresti usare un Mixin per questo? Vedere https://facebook.github.io/react/docs/reusable-components.html

Anche se stanno cadendo in disgrazia vedere https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750

potrebbe essere utile

+0

Concordo sul fatto che mixin è una soluzione migliore qui rispetto all'esportazione di una funzione comune. –

+0

@TaoHuang Alcune cose da considerare, 1.Mixins non sono a prova di futuro e verranno utilizzate sempre meno nelle moderne app, 2.Utilizzando una funzione esportata agnostica la struttura del codice - è possibile utilizzare facilmente tali funzioni su qualsiasi altro progetto js. Leggi anche questo post per sapere perché NON usare Mixins -> https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html – deowk

+0

Un mixin può accedere e modificare lo stato, mentre un tratto non lo fa, e poiché l'OP sta dicendo che vogliono qualcosa da trattare come una libreria di funzioni, un mixin non sarebbe la soluzione giusta. – HoldOffHunger

1

Ecco alcuni esempi su come si può riutilizzare una funzione (FetchUtil.handleError) in un componente React (App).

Soluzione 1: Utilizzando CommonJS sintassi modulo

module.exports = { 
    handleError: function(response) { 
    if (!response.ok) throw new Error(response.statusText); 
    return response; 
    }, 
}; 

Soluzione 2: Usando "createClass" (React V16)

util/FetchUtil.js

const createReactClass = require('create-react-class'); 

const FetchUtil = createReactClass({ 
    statics: { 
    handleError: function(response) { 
     if (!response.ok) throw new Error(response.statusText); 
     return response; 
    }, 
    }, 
    render() { 
    }, 
}); 

export default FetchUtil; 

Nota: se stai usando React v15.4 (o sotto) è necessario importare createClass come segue:

import React from 'react'; 
const FetchUtil = React.createClass({}); 

Fonte: https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactcreateclass

Component (che riutilizza FetchUtil)

componenti/App.jsx

import Categories from './Categories.jsx'; 
import FetchUtil from '../utils/FetchUtil'; 
import Grid from 'material-ui/Grid'; 
import React from 'react'; 

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {categories: []}; 
    } 

    componentWillMount() { 
    window 
     .fetch('/rest/service/v1/categories') 
     .then(FetchUtil.handleError) 
     .then(response => response.json()) 
     .then(categories => this.setState({...this.state, categories})); 
    } 

    render() { 
    return (
     <Grid container={true} spacing={16}> 
     <Grid item={true} xs={12}> 
      <Categories categories={this.state.categories} /> 
     </Grid> 
     </Grid> 
    ); 
    } 
} 

export default App; 
Problemi correlati