Ich habe mehrere Komponenten, die alle dasselbe tun müssen. (Eine einfache Funktion, die ihre untergeordneten Komponenten abbildet und jedem etwas antut). Im Moment definiere ich diese Methode in jeder der Komponenten. Aber ich möchte es nur einmal definieren.
Ich könnte es in der obersten Komponente definieren und es dann als Requisite weitergeben. Das fühlt sich aber nicht ganz richtig an. Es ist eher eine Bibliotheksfunktion als eine Requisite. (Es kommt mir vor).
Was ist der richtige Weg, dies zu tun?
Antworten:
Wenn Sie so etwas wie browserify verwenden , können Sie eine externe Datei haben, dh util.js, die einige Dienstprogrammfunktionen exportiert.
var doSomething = function(num) { return num + 1; } exports.doSomething = doSomething;
Dann benötigen Sie es nach Bedarf
var doSomething = require('./util.js').doSomething;
quelle
Utils.js mit der neuesten Javascript ES6-Syntax
Erstellen Sie die
Utils.js
Datei wie folgt mit mehreren Funktionen usw.const someCommonValues = ['common', 'values']; export const doSomethingWithInput = (theInput) => { //Do something with the input return theInput; }; export const justAnAlert = () => { alert('hello'); };
Importieren Sie dann in Ihren Komponenten, für die Sie die util-Funktionen verwenden möchten, die spezifischen Funktionen, die benötigt werden. Sie müssen nicht alles importieren
import {doSomethingWithInput, justAnAlert} from './path/to/utils.js/file'
Verwenden Sie dann diese Funktionen innerhalb der Komponente wie folgt:
justAnAlert(); <p>{doSomethingWithInput('hello')}</p>
quelle
/file
am Ende der Importzeile?Wenn Sie den Status in Hilfsfunktionen ändern möchten, gehen Sie wie folgt vor:
Erstellen Sie eine Helpers.js-Datei:
export function myFunc(){ return this.state.name; //define it according to your needs }
Importieren Sie die Hilfsfunktion in Ihre Komponentendatei:
import {myFunc} from 'path-to/Helpers.js'
Fügen Sie in Ihrem Konstruktor diese Hilfsfunktion zur Klasse hinzu
constructor(){ this.myFunc = myFunc.bind(this) }
Verwenden Sie in Ihrer Renderfunktion Folgendes:
render(){ <div>{this.myFunc()}</div> }
quelle
Hier einige Beispiele, wie Sie eine Funktion (
FetchUtil.handleError
) in einer React-Komponente (App
) wiederverwenden können .Lösung 1: Verwenden der CommonJS-Modulsyntax
module.exports = { handleError: function(response) { if (!response.ok) throw new Error(response.statusText); return response; }, };
Lösung 2: Verwenden von "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: Wenn Sie React v15.4 (oder niedriger) verwenden, müssen Sie Folgendes importieren
createClass
: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 FetchUtil wiederverwendet)
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;
quelle
Eine andere solide Option außer dem Erstellen einer Util-Datei wäre die Verwendung einer Komponente höherer Ordnung zum Erstellen eines
withComponentMapper()
Wrappers. Diese Komponente würde eine Komponente als Parameter aufnehmen und mit dem zurückgebencomponentMapper()
als Requisite übergebenen Funktion zurück.Dies wird in React als bewährte Methode angesehen. Wie das geht, erfahren Sie hier im Detail.
quelle
Klingt nach einer Utility-Funktion. In diesem Fall sollten Sie sie in ein separates statisches Utility-Modul einfügen.
Andernfalls können Sie bei Verwendung eines Transpilers wie Babel die statischen Methoden von es7 verwenden:
class MyComponent extends React.Component { static someMethod() { ...
Wenn Sie React.createClass verwenden, können Sie auch das statische Objekt verwenden:
var MyComponent = React.createClass({ statics: { customMethod: function(foo) { return foo === 'bar'; } }
Ich rate jedoch nicht zu diesen Optionen. Es ist nicht sinnvoll, eine Komponente für eine Dienstprogrammmethode einzuschließen.
Außerdem sollten Sie keine Methode als Requisite durch alle Ihre Komponenten weitergeben, da dies sie eng koppelt und das Refactoring schmerzhafter macht. Ich empfehle ein einfaches altes Utility-Modul.
Die andere Möglichkeit besteht darin, ein Mixin zu verwenden, um die Klasse zu erweitern, aber ich empfehle dies nicht, da Sie dies in es6 + nicht tun können (und ich sehe den Vorteil in diesem Fall nicht).
quelle
React.createClass
ist seit React 15.5.0 veraltet. create-react-app schlägtcreate-react-class
stattdessen die Verwendung des npm-Moduls vor.doSomething.js
eine Datei mit mehreren ähnlichen "Dienstprogramm" -Funktionen, z. B.utils.js
und die Funktionen dort importieren, wo Sie sie verwenden müssenIm Folgenden werden zwei Stile gezeigt, und Sie sollten auswählen, in welchem Verhältnis die Logik der Komponenten zueinander steht.
Style 1 - Relativ bezogenen Komponenten werden können erstellt mit Callback - Referenzen, wie diese, in
./components/App.js
...<SomeItem ref={(instance) => {this.childA = instance}} /> <SomeOtherItem ref={(instance) => {this.childB = instance}} />
Und dann können Sie verwenden gemeinsam genutzte Funktionen zwischen ihnen so ...
this.childA.investigateComponent(this.childB); // call childA function with childB as arg this.childB.makeNotesOnComponent(this.childA); // call childB function with childA as arg
Stil 2 - Util-Komponenten können wie folgt erstellt werden
./utils/time.js
:export const getTimeDifference = function (start, end) { // return difference between start and end }
Und dann können sie so verwendet werden , in
./components/App.js
...import React from 'react'; import {getTimeDifference} from './utils/time.js'; export default class App extends React.Component { someFunction() { console.log(getTimeDifference("19:00:00", "20:00:00")); } }
Welche verwenden?
Wenn die Logik relativ verwandt ist (sie werden nur in derselben App zusammen verwendet), sollten Sie Zustände zwischen Komponenten teilen. Wenn Ihre Logik jedoch entfernt verwandt ist (z. B. Math Util, Text Formatierungs Util), sollten Sie Util-Klassenfunktionen erstellen und importieren.
quelle
Solltest du dafür kein Mixin verwenden? Siehe https://facebook.github.io/react/docs/reusable-components.html
Obwohl sie in Ungnade fallen, siehe https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750
Könnte nützlich sein
quelle