我有一个尝试使用的Fields
组件,有时是自己使用的,有时是从FieldArray
组件内部使用的。我在下面添加了一个带有简化模型的代码片段。
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
组件时,来自renderSharedComponent
内部的fields
参数具有以下形式:
{
hashes: [
{
value: { input: {...}, meta: {...} },
valueIsRegex: { input: {...}, meta: {...} }
}
],
names: [ 'hashes[0].value' , 'hashes[0].valueIsRegex' ]
}
如果我将在具有不同名称(假设是paths
)的FieldArray
组件中使用Fields
组件,则names属性将相应地更改(例如。names: [ 'paths[0].value' , 'paths[0].valueIsRegex' ]
)。
我正在尝试以一种通用的方式获取value
和valueIsRegex
对象,以支持上面提到的任何一种情况。
现在,我已经创建了一个函数,其中我使用RegEx来确定字段。但我想知道是否有人知道更好的方法(也许有一个Redux Form util,我在阅读文档时可能遗漏了它)。
发布于 2017-04-08 23:28:05
也有同样的问题。可能惯用的方法是使用formValueSelector
function。但这样做有点像样板,因为你必须在整个表单中传递选择器(据我所知)。就我个人而言,我也做了基于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"></i>
</span>
<span className="label__text">{groupData.title.input.value}</span>
</div>
);
};
发布于 2017-08-21 16:22:08
redux-form有一个隐藏的实用函数,这在这里很有用,但我不知道你是否可以在未来的版本中依赖它的可用性:
import structure from "redux-form/lib/structure/plain";
function RenderRow({ names, ...props }) {
const fields = {};
names.forEach(n => (fields[n] = structure.getIn(props, n)));
}
https://stackoverflow.com/questions/39730460
复制相似问题