我有一个通过高阶组件管理受控输入的表单。结构是这样的:
function BaseField(WrappedComponent) {
class WrappedField extends React.Component {
constructor(props) {
super(props);
this.state = {
value: '',
active: false,
}
}
setValue = (e) => {
this.setState({ value: e.target.value })
}
...
<WrappedComponent
{...this.props}
value={this.state.value}
set={this.setValue}
active={this.state.active}
/>
....
import React from 'react';
import BaseField from './BaseField';
const TextField = (props) => {
return <input
value={props.value}
onChange={props.set}
name={props.name}
type={props.type}
/>
}
export default BaseField(TextField);
使用TextField
时效果很好 - 但是,我想更灵活地使用它 - 例如,我希望能够在某些情况下增强onChange
功能,总是让它设置状态,但也让它根据TextField
中使用的组件中的状态或函数执行其他操作。
我是否误解了HOC的工作原理?
答案 0 :(得分:1)
您可以使用createChainedFunction
中的react-bootstrap:
function createChainedFunction(...funcs) {
return funcs
.filter(f => f != null)
.reduce((acc, f) => {
if (typeof f !== 'function') {
throw new Error('Invalid Argument Type, must only provide functions, undefined, or null.');
}
if (acc === null) {
return f;
}
return function chainedFunction(...args) {
acc.apply(this, args);
f.apply(this, args);
};
}, null);
}
来自我的react utils:
export function copyPropsWithout(props, without) {
const propKeys = Object.keys(props);
const passProps = propKeys.reduce((obj, propKey) => {
if (without.indexOf(propKey) === -1) {
obj[propKey] = props[propKey];
}
return obj;
}, {});
return passProps;
}
我将这些添加到您的工具中,然后使用它们:
...
<WrappedComponent
{...copyPropsWithout(this.props, ['onChange'])}
value={this.state.value}
set={createChainedFunction(this.setValue, this.props.onChange}}
active={this.state.active}
/>
....