2017-08-07 38 views
2

当两个组件共享某些相同的方法但布局不同时,如何避免编写相同的代码?如何避免在具有不同布局的组件中编写相同的逻辑?

下面的示例组件具有一个方法“renderLastItem”,它使用由父组件传递的prop“something”。

我想过使用高阶组件模式,但我不确定我可以传递道具作为高阶组件的参数。

下面的示例代码非常简单,所以在此示例代码中,我只需要使用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的函数。所以,你可以创建一个高阶withLastOfSomething组件就像这样:

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

或用ES6箭头的功能,更紧凑是这样的:

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

非常感谢你!所以在我的例子中,我会写代码“export default()”? – hytm

+0

这种模式很酷的事情之一是,您可以将它作为组件固有的概念应用 - 在这种情况下,您可以做类似的事情 - 或者作为组件父项的固有概念,其中你只需要在渲染时应用它。无论哪个对你最有意义! – 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

相关问题