2016-10-06 1 views
3

상태에 연결하는 일부 코드를 재사용하기 위해 Higher Order Component (HOC) 패턴을 사용하려고하고 Redux Form formValueSelector 메소드를 사용하고 있습니다.Higher Order 구성 요소를 호출 할 때 React에서 클래스 외부의 소품에 액세스하십시오.

formValueSelector는 양식의 이름을 참조해야합니다. 이 항목을 동적으로 설정하고 항목 값이 필요할 때마다이 HOC를 사용할 수 있어야합니다. 계산에 항목 값을 사용합니다.

아래 코드에서 HOC는 구성 요소와 문자열을 전달합니다. 부모 (양식)에서 전달 된 propFormName으로 설정하고 싶습니다.

나는 HOC 패턴을 처음 사용하기 때문에 어떤 조언을 가장 높이 평가할 수 있습니다.

HOC

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import { formValueSelector } from 'redux-form'; 

function FormItemsValueSelectorHOC(FormElement, formName) { 
    const selector = formValueSelector(formName); 
    @connect(state => { 
    console.log(state); 
    const items = selector(state, 'items'); 
    return { 
     items 
    }; 
    }, null) 
    class Base extends Component { 
    render() { 
     return (
     <FormElement {...this.props} /> 
    ); 
    } 
    } 
    return Base; 
} 
export default FormItemsValueSelectorHOC; 

포장 구성 요소

import React, { Component, PropTypes } from 'react'; 
import { Field } from 'redux-form'; 
import formItemsValueSelectorHOC from '../Utilities/FormItemsValueSelectorHOC'; 

const renderField = ({ placeholder, input, type}) => { 
    return (
    <input 
     {...input} 
     placeholder={placeholder} 
     type={type} 
    /> 
); 
}; 

class StatementLineItemDesktop extends Component { 
    static propTypes = { 
    items: PropTypes.array.isRequired, 
    index: PropTypes.number.isRequired, 
    item: PropTypes.string.isRequired, 
    fields: PropTypes.object.isRequired, 
    formName: PropTypes.string.isRequired 
    }; 

    calculateLineTotal(items, index) { 
    let unitPrice = '0'; 
    let quantity = '0'; 
    let lineTotal = '0.00'; 
    if (items) { 
     if (items[index].price) { 
     unitPrice = items[index].price.amountInCents; 
     } 
     quantity = items[index].quantity; 
    } 
    if (unitPrice && quantity) { 
     lineTotal = unitPrice * quantity; 
     lineTotal = Number(Math.round(lineTotal+'e2')+'e-2').toFixed(2); 
    } 
    return <input value={lineTotal} readOnly placeholder="0.00" />; 
    } 

    render() { 
    const { items, index, item, fields, formName} = this.props; 
    return (
     <tr id={`item-row-${index}`} key={index} className="desktop-only"> 
     <td> 
      <Field 
      name={`${item}.text`} 
      type="text" 
      component={renderField} 
      placeholder="Description" 
      /> 
     </td> 
     <td> 
      <Field 
      name={`${item}.quantity`} 
      type="text" 
      component={renderField} 
      placeholder="0.00" 
      /> 
     </td> 
     <td> 
      <Field 
      name={`${item}.price.amountInCents`} 
      type="text" 
      component={renderField} 
      placeholder="0.00" 
      /> 
     </td> 
     <td className="last-col"> 
      <Field 
      name={`${item}.price.taxInclusive`} 
      type="hidden" 
      component="input" 
      /> 
      {::this.calculateLineTotal(items, index)} 
      <a 
      className="remove-icon" 
      onClick={() => fields.remove(index)} 
      > 
      <span className="icon icon-bridge_close" /> 
      </a> 
     </td> 
     </tr> 
    ); 
    } 
} 

export default formItemsValueSelectorHOC(StatementLineItemDesktop, 'editQuote'); 
+0

나에게 명확한 지 모르겠지만 반응 구성 요소'StatementLineItemsDesktop' 클래스를 내보내고 호출 할 수 있도록 부모 구성 요소가 선언 된 파일에서이 React 구성 요소를'formItemsValueSelectorHOC' 함수와 함께 가져 오는 것으로 생각 해보았습니까 두 번째 인수로'this.props.formName'을 사용하여 부모의'render()'메소드에있는이 HOC? – dzv3

답변

4

TLDR : ownProps 매개 변수

당신이

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import { formValueSelector } from 'redux-form'; 

function FormItemsValueSelectorHOC(FormElement) { 
    @connect((state, ownProps) => { 
    const formName = ownProps.formName; 
    const selector = formValueSelector(formName); 
    const items = selector(state, 'items'); 
    return { 
     items 
    }; 
    }, null) 
    class Base extends Component { 
    render() { 
     // Now in here you should omit `formName` from the props you are 
     // passing to your Form Element since it's not used overthere 
     return (
     <FormElement {...this.props} /> 
    ); 
    } 
    } 
    return Base; 
} 
export default FormItemsValueSelectorHOC; 

을해야 할 일의 초안이 w를 사용 아픈 당신이 당신의 연결 요소

formItemsValueSelectorHOC(StatementLineItemDesktop); 

을 만들 것입니다 방법이있을 그리고 이것은

<ConnectedStatementLineItemDesktop formName={"editQuote"} /> 

이 나를 좀 더 설명하게 당신이 그것을 사용하는 방법이 얼마나이 작품

것은 당신을 React-Redux API가 누락되었습니다. 이미 많은 유스 케이스를 고려하고 있기 때문에 더 많은 것을 탐색해야합니다.

그래서 React-Redux의 connect func 첫 번째 매개 변수는 mapStateToProps입니다.

mapStateToProps(state, [ownProps]): stateProps 

내가 말하고자하는 것은이 ownProps 매개 변수 :

이는 서명입니다.

ownProps에는 연결된 구성 요소로 전달되는 모든 소품이 포함되어 있습니다.

그냥 설명을 위해, 당신은 이러한 구성 요소

  • 일반 구성 요소 : 즉 ConnectedBase = connect(mapStateToProps)(Base)

그래서,이 정보에서, 당신의 HOC 기능이 FormItemsValueSelectorHOC 전화 : StatementLineItemDesktopBase

  • 연결된 구성 요소 즉, 는 ConnectedBase의 변형을 반환합니다.

    그래서, 어떤 소품 당신이 ConnectedBase에 전달하거나 어떤 구성 요소는 당신이 당신의 특정한 경우에, BTW ownProps

    에서 액세스 할 수 있습니다 FormItemsValueSelectorHOC에서 반환이 당신의 mapStateToProps

    function mapStateToProps(state, ownProps) { 
        const formName = ownProps.formName; 
        const selector = formValueSelector(formName); 
        const items = selector(state, 'items'); 
        return { 
        items 
        }; 
    } 
    

    건에이다 참고로 connect은 HOC이기 때문에 정상적인 구성 요소로 수행하는 대부분의 작업을 연결된 구성 요소와 함께 수행 할 수 있다고 생각하는 것은 논리적으로 생각합니다. connect 소스를 읽으시겠습니까? 다르다 ficult 그래서 당신은 아마이 대답의 더 많은 것을 탐험하고 이해할 수 있습니다.

    도움이 되었기를 바랍니다.

  • +0

    글쎄 대답 !! –

    관련 문제