【发布时间】:2017-02-14 14:52:52
【问题描述】:
我正在尝试使用高阶组件(HOC)模式来重用一些连接到状态并使用 Redux Form formValueSelector 方法的代码。
formValueSelector 需要一个引用表单名称的字符串。我想动态设置它,并能够在我需要项目值的时候使用这个 HOC。我使用项目值进行计算。
在下面的代码中,HOC 被传递了组件和一个字符串。我想将此设置为从父(表单)传入的道具formName。
我是 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');
【问题讨论】:
-
不确定我是否清楚,但是您是否考虑过仅导出反应组件
StatementLineItemsDesktop类并将此反应组件与formItemsValueSelectorHOC函数一起导入父组件所在的文件中声明这样你就可以在你父母的render()方法中使用this.props.formName作为第二个参数来调用这个 HOC?
标签: javascript reactjs react-redux redux-form