2017-08-07 11 views
2

2つのコンポーネントが同じメソッドを共有していてレイアウトが異なる場合、同じコードを書くことを避けるにはどうすればよいですか?レイアウトが異なるコンポーネントに同じロジックを書き込まないようにするにはどうすればよいですか?

以下のサンプルコンポーネントには、親コンポーネントが渡したprop "something"を使用するメソッド "renderLastItem"があります。

Higher Order Component Patternを使用することを考えましたが、Higher Order Componentの引数として小道具を渡すことはできません。

以下のサンプルコードは非常にシンプルなので、このサンプルコードでは、If文を使用してコンポーネントのタイプに応じてレイアウトを変更するだけで、実際のコードではコードが増え、避けたいif文を使用して、コンポーネントのタイプに応じてレイアウトを変更します。

同じロジックを複数のコンポーネントに書き込まないようにするにはどうすればよいですか?

ComponentA

import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 

const propTypes = {}; 
const defaultProps = {}; 

class SampleA extends Component { 

    constructor(props) { 
     super(props); 
    } 


    renderLastItem() { 

     if(!this.props.something) { 
      return null; 
     } 

     return this.props.something[this.props.something.length - 1]; 

    } 


    render() { 

     return (

      <div> 
       <h1>Something</h1> 
       <p>{this.renderLastItem()}</p> 
      </div> 

     ); 

    } 
} 

SampleA.propTypes = propTypes; 
SampleA.defaultProps = defaultProps; 

export default SampleA; 

ComponentB

import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 

const propTypes = {}; 
const defaultProps = {}; 

class SampleB extends Component { 

    constructor(props) { 
     super(props); 
    } 


    renderLastItem() { 

     if(!this.props.something) { 
      return null; 
     } 

     return this.props.something[this.props.something.length - 1]; 

    } 


    render() { 

     return (

      <div> 
       <ul> 
        <li>Something</li> 
        <li>Something else</li> 
        <li>{this.renderLastItem()}</li> 
       </ul> 
      </div> 

     ); 

    } 
} 

SampleB.propTypes = propTypes; 
SampleB.defaultProps = defaultProps; 

export default SampleB; 

答えて

1

あなたは絶対に高位コンポーネントに小道具を渡すことができます! HOCは単に、引数としてComponentをとり、結果として別のComponentを返す関数です。

function withLastOfSomething(Component) { 
    return function({something, ...otherProps}) { 
    const item = something ? something[something.length - 1] : null; 
    return <Component item={item} {...otherProps} />; 
    } 
} 

またはES6の矢印機能と、さらにコンパクトに、このような:だから、ちょうどこのように高次withLastOfSomethingコンポーネントを作成することができ

const withLastOfSomething = (Component) => ({something, ...otherProps}) => { 
    const item = something ? something[something.length - 1] : null; 
    return <Component item={item} {...otherProps} />; 
} 

そして、このようにそれを使用します。

const SampleBWithLastOfSomething = withLastOfSomething(SampleB); 

return (<SampleBWithLastOfSomething something={...} />); 
+0

ありがとう!だから私の例では、私はshouleコードを書き出す "エクスポートのデフォルト()"? – hytm

+0

このパターンのすばらしい点の1つは、コンポーネントに固有の概念として適用することができます。その場合は、そういったことをするか、コンポーネントの親に固有の概念として適用します。あなたはレンダリング時にそれを適用するだけです。どちらがあなたにとって最も理にかなっています! – Hamms

2

あなたが必要な場所のように、それをインポートし

export default renderLastItem = (passedProps) => { 

    if(!passedProps) { 
     return null; 
    } 

    return passedProps [passedProps.length - 1] 

    } 

、渡された小道具を取り、ロジックを実行機能を分離することができますこれは:

import renderLastItem from './somewhere' 

export default class SampleA extends Component { 

    render() { 

    return (

     <div> 
      <h1>Something</h1> 
      <p>{renderLastItem(this.props.something)}</p> 
     </div> 
    ) 
    } 
} 
+1

ありがとうございます!今回はこのアプローチを取った! – hytm

関連する問題