2015-10-01 16 views
25

私は同じことをすべて行う必要がある複数のコンポーネントを持っています。 (子コンポーネントをマップし、それぞれに何かを実行する単純な関数)。現時点では、各コンポーネントでこのメソッドを定義しています。しかし、私はそれを一度定義したいだけです。Reactのコンポーネント間で関数を共有する正しい方法

Iは、トップレベルのコンポーネントでそれを定義し、小道具としてそれを渡すことができます。しかし、それはまったく正しいとは思わない。これは、支柱よりもライブラリ関数です。 (私にはそう思われる)。

これを行うための正しい方法は何ですか?

答えて

11

あなたがbrowserifyのようなものを使用した場合、あなたは、いくつかのユーティリティ関数をエクスポートする外部ファイルすなわちのutil.jsを持つことができます。

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

exports.doSomething = doSomething; 

、必要に応じて次に

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

を次のように4(または以下)あなたはcreateClassをインポートする必要がありますこれらの関数が状態を操作する場合、何が行われるべきですか? – aks

+0

@AnkitSinghaniyaそれはあなたのアプリのフロントエンド状態を管理するために何を使用しているのですか? – deowk

+1

私は反応状態を使用しています。 – aks

3

が、その場合には、なぜ別の静的なユーティリティモジュールに入れていない、効用関数のように聞こえる?それを必要としますか

そうでない場合は、ES7の静的メソッドを利用することができるバベルのようなtranspiler使用:

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

さもないと、あなたがReact.createClassを使用している場合はstaticsオブジェクトを使用することができます

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

をしかし、私はこれらのオプションについてはアドバイスしていませんが、ユーティリティメソッドにコンポーネントを含めることは意味がありません。

また、あなたはそれがしっかりとカップルそれら意志小道具として、すべてのコンポーネントを介し法を伝承し、より多くの痛みを伴うリファクタリング作るべきではありません。私は普通の古いユーティリティモジュールに助言する。

他のオプションは、クラスを拡張するためにミックスインを使用することですが、私はあなたがES6 +でそれを行うことができないとして(と私は、この場合の利点が表示されていない)ことをお勧めしません。

+0

ミックスインに関する情報は有用です。この場合、ライフサイクルイベントで自動的に何かを実行するのではなく、条件付きで関数を使用したいと考えています。そう。あなたが言うように、普通の古いユーティリティ関数は、行く方法です。 –

+0

注:「React.createClass''は、React 15.5.0以降、廃止予定です。 create-react-appでは、代わりにnpmモジュール '' create-react-class''を使用するよう提案しています。 –

2

このためにMixinを使用しないでください。彼らは好意から下落しているが、ここでhttps://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750

+0

mixinは、共通の関数をエクスポートするよりも優れたソリューションです。 –

+0

@ TaoHuangいくつか考慮すべき点は、1.Mixinsは将来の証明ではなく、現代的なアプリケーションではあまり使用されなくなります。2.エクスポートされた関数を使用すると、コードフレームワークに無関心になります。また、Mixinsを使用しない理由についてのこの記事をお読みください。https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html – deowk

+0

mixinは、状態、特性はありませんが、OPは彼らが関数ライブラリとして扱うことを望んでいると言っているので、ミックスインは正しい解決策ではありません。 – HoldOffHunger

1

便利かもしれません参照https://facebook.github.io/react/docs/reusable-components.html

を参照してください、あなたが反応コンポーネント(App)で機能(FetchUtil.handleError)を再利用することができます方法についていくつかの例があります。

解決策1:

​​

CommonJSモジュール構文を用いて溶液2: "createClass" を使用して(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; 

注:もしあなたはReact v15を使用しています。

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

出典::(FetchUtilを再利用)https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactcreateclass

コンポーネント

コンポーネント/ 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; 
関連する問題