2015-10-01 15 views
25

zu teilen Ich habe mehrere Komponenten, die alle dasselbe tun müssen. (Eine einfache Funktion, die ihre Kindkomponenten abbildet und mit jedem etwas tut). Im Moment definiere ich diese Methode in jeder der Komponenten. Aber ich will es nur einmal definieren.Korrekten Weg, Funktionen zwischen Komponenten in React

Ich könnte es in der Top-Level-Komponente definieren und dann als Stütze übergeben. Aber das fühlt sich nicht ganz richtig an. Es ist mehr eine Bibliotheksfunktion als eine Stütze. (Es kommt mir vor).

Was ist der richtige Weg, dies zu tun?

Antwort

11

Wenn Sie etwas wie browserify verwenden, können Sie eine externe Datei haben, d. H. Util.js, die einige Funktionen des Dienstprogramms exportiert.

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

exports.doSomething = doSomething; 

erfordert es dann als

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

Was sollte getan werden, wenn diese Funktionen den Zustand manipulieren? – aks

+0

@AnkitSinghaniya Das hängt davon ab, was Sie verwenden, um den Front-End-Zustand Ihrer App zu verwalten? – deowk

+1

Ich verwende Reaktionszustände. – aks

3

Klingt wie eine Nutzenfunktion, in diesem Fall, warum es nicht in einem gesonderten statischen Dienstprogramm-Modul setzen?

Andernfalls, wenn ein Transpiler wie Babel verwenden Sie den Einsatz von ES7 statischen Methoden machen können:

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

Oder wenn Sie React.createClass verwenden, können Sie das statics Objekt verwenden:

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

Allerdings rate ich diese Optionen nicht, es macht keinen Sinn, eine Komponente für eine Utility-Methode einzuschließen.

Auch sollten Sie nicht eine Methode durch alle Ihre Komponenten als eine Stütze durchgehen, es wird sie fest koppeln und Refactoring schmerzhafter machen. Ich empfehle ein einfaches altes Utility-Modul. Die andere Option ist die Verwendung eines Mixins, um die Klasse zu erweitern, aber ich empfehle das nicht, da es in es6 + nicht möglich ist (und ich sehe in diesem Fall keinen Vorteil).

+0

Die Information über Mixins ist nützlich. In diesem Fall möchte ich die Funktion bedingt verwenden, anstatt dass bei einem Lebenszyklusereignis automatisch etwas passiert. Damit. Wie Sie sagen, ist eine einfache alte Dienstprogrammfunktion der Weg zu gehen. –

+0

Hinweis: 'React.createClass'' ist seit React 15.5.0 veraltet. create-react-app schlägt stattdessen die Verwendung des npm-Moduls '' create-react-class'' vor. –

2

Sollten Sie kein Mixin dafür verwenden? Siehe https://facebook.github.io/react/docs/reusable-components.html

Obwohl sie in Ungnade fallen sehen https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750

nützlich sein könnte

+0

Ich stimme zu, dass Mixin hier eine bessere Lösung ist, als nur eine gemeinsame Funktion zu exportieren. –

+0

@TaoHuang Einige Dinge zu beachten, 1.Mixins sind nicht zukunftssicher und werden immer weniger in modernen apps, 2. Using eine exportierte Funktion macht Ihre Code-Framework agnostic - Sie könnten diese Funktionen leicht auf andere js-Projekt verwenden. Lies bitte auch diesen Beitrag darüber, warum du Mixins NICHT verwenden darfst -> https://facebook.github.io/react/blog/2016/07/13/mixins-consided-harmful.html – deowk

+0

Ein Mixin darf auf den Status zugreifen und ihn ändern, während ein Merkmal dies nicht tut, und da das OP sagt, dass sie etwas wollen, das als Funktionsbibliothek behandelt werden soll, wäre ein Mixin nicht die richtige Lösung. – HoldOffHunger

1

Hier sind einige Beispiele, wie Sie eine Funktion wieder verwenden können (FetchUtil.handleError) in einer Reaktion Komponente (App).

Lösung 1: Mit Commonjs Modul Syntax

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

Lösung 2: Mit "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; 

Hinweis: Bei Sie verwenden React v15.4 (oder unten) müssen Sie createClass importieren wie folgt:

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

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

Komponente (die wieder verwendet FetchUtil)

Komponenten/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; 
Verwandte Themen