2016-09-27 3 views
0

구성 요소 중 하나에서 때때로 가끔씩 사용하려고 시도한 Fields 구성 요소가 있습니다. 아래에 간단한 모델로 스 니펫을 추가했습니다.FieldArray 구성 요소의 Redux 양식 필드 구성 요소 사용

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { createStore, combineReducers } from 'redux'; 
import { Provider } from 'react-redux'; 
import { reduxForm, Fields, FieldArray, reducer as formReducer } from 'redux-form'; 

const reducers = { 
    form: formReducer 
}; 

const reducer = combineReducers(reducers); 

const store = createStore(reducer); 

const renderSharedComponent = (fields) => { 
    console.log(fields); 
    return (<div>Shared Component</div>); 
}; 

const renderHashes = ({ fields }) => (
    <div> 
    { 
     fields.map((field) => (
     <Fields 
      key={ field } 
      names={ [`${field}.value`, `${field}.valueIsRegex`] } 
      component={ renderSharedComponent } 
     /> 
    )) 
    } 
    </div> 
); 

const ReactComponent =() => (
    <div> 
    <FieldArray 
     name="hashes" 
     component={ renderHashes } 
    /> 
    <Fields 
     names={ ['value', 'valueIsRegex'] } 
     component={ renderSharedComponent } 
    /> 
    </div> 
); 

const ReduxForm = reduxForm({ 
    form: 'default', 
    initialValues: { 
    hashes: [{}] 
    } 
})(ReactComponent); 

ReactDOM.render((
    <div> 
    <Provider store={ store }> 
     <ReduxForm /> 
    </Provider> 
    </div> 
), document.getElementById('content')); 

내가 단독으로 Fields 구성 요소를 사용하는 경우, renderSharedComponent 내부에서 fields 인수는 다음과 같은 형식이 있습니다

{ 
    value: { input: {...}, meta: {...} }, 
    valueIsRegex: { input: {...}, meta: {...} }, 
    names: [ 'value' , 'valueIsRegex' ] 
} 

나는 FieldArray 구성 요소 내부의 Fields 구성 요소를 사용

, 내부에서 fields 인수 renderSharedComponent의 형식은 다음과 같습니다.

{ 
    hashes: [ 
     { 
     value: { input: {...}, meta: {...} }, 
     valueIsRegex: { input: {...}, meta: {...} } 
     } 
    ], 
    names: [ 'hashes[0].value' , 'hashes[0].valueIsRegex' ] 
} 

다른 이름을 가진 FieldArray 구성 요소 안에 Fields 구성 요소를 사용하는 경우 (예 : paths라고 가정) 이름 속성이 이에 따라 변경됩니다 (예 : names: [ 'paths[0].value' , 'paths[0].valueIsRegex' ]).

나는 위에서 제시 한 모든 경우를 지원하는 일반적인 방법으로 valuevalueIsRegex 개체를 얻으려고합니다.

지금은 RegEx를 사용하여 필드를 결정하는 함수를 만들었습니다. 하지만 누구든지이 작업을 수행하는 더 좋은 방법을 알고 있는지 궁금해하고 있습니다. 아마도 문서를 읽을 때 놓친 Redux Form 유틸리티가있을 수 있습니다.

답변

1

같은 문제가 있습니다. 관용적 인 방법은 formValueSelectorfunction을 사용하는 것일 수 있습니다. 그러나 그 방식은 조금 더 보편적입니다. 선택자를 (내가 이해하는 한) 양식을 통해 내려야합니다. 개인적으로 저는 regexp 기반 함수도 개인적으로했습니다. 향후 버전에서 가용성 것

/** 
 
* Converts path expression string to array 
 
* @param {string} pathExpr path string like "bindings[0][2].labels[0].title" 
 
* @param {Array<string|int>} array path like ['bindings', 0, 2, 'labels', 0, 'title'] 
 
*/ 
 
function breakPath(pathExpr) { 
 
    return pathExpr 
 
     .split(/\]\.|\]\[|\[|\]|\./) 
 
     .filter(x => x.length > 0) 
 
     .map(x => isNaN(parseInt(x)) ? x : parseInt(x)); 
 
} 
 

 
/** 
 
* Executes path expression on the object 
 
* @param {string} pathExpr – path string like "bindings[0][2].labels[0].title" 
 
* @param {Object|Array} obj - object or array value 
 
* @return {mixed} a value lying in expression path 
 
* @example 
 
* ``` 
 
* execPath('books[0].title', {books: [{title: 'foo'}]}) 
 
* // yields 
 
* 'foo' 
 
* ``` 
 
*/ 
 
function execPath(pathExpr, obj) { 
 
    const path = breakPath(pathExpr); 
 
    if (path.length < 1) { 
 
     return obj; 
 
    } 
 
    return path.reduce(function(obj, pathPart) { 
 
     return obj[pathPart]; 
 
    }, obj); 
 
} 
 

 
/** 
 
* A generic GroupLabelField that relies on valueBasePath 
 
*/ 
 
const GroupLabelField = (props) => { 
 
    const groupData = execPath(props.valueBasePath, props); 
 
    return (
 
     <div className={`label__content label__content_icon_${groupData.objectType.input.value}`}> 
 
      <span className="label__remove" 
 
        onClick={(e) => { props.handleRemove(); e.stopPropagation(); }} 
 
      > 
 
       <i className="material-icons material-icons_12 material-icons_top">&#xE5CD;</i> 
 
      </span> 
 
      <span className="label__text">{groupData.title.input.value}</span> 
 
     </div> 
 
    ); 
 
};

0

REDUX 형태가 여기에 유용 숨겨진 유틸리티 기능을 가지고 있지만, 당신이 그것에 의존 할 수 있을지 모르겠어요 :

여기있다
import structure from "redux-form/lib/structure/plain"; 

function RenderRow({ names, ...props }) { 
    const fields = {}; 
    names.forEach(n => (fields[n] = structure.getIn(props, n))); 
} 

도 참조하십시오. this github issue

관련 문제