我昨天问了这个问题:React sharing method across components
import React from 'react';
class LoginForm extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
由于我在整个应用程序中多次重复使用handleChange(e)
,因此我决定将其分成一个更高阶的组件:
import React from 'react';
const withHandleChange = (WrappedComponent) => {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
handleChange = e => {
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<WrappedComponent
handleChange={this.handleChange}
form={this.state}
{...this.props}
/>
);
}
}
};
export default withHandleChange;
[而不是使LoginForm
保持输入字段的状态,而是现在让HOC完成该工作,然后将这种状态作为form
的支持传递给他人。我也将handleChange
方法作为道具传递下来。
并且在原始的LoginForm
组件中,我呈现了以下内容:
<input type="text" placeholder="Email" name="email" value={this.props.form.email} onChange={this.props.handleChange} />
我这样包裹LoginForm
:
const WrappedLoginForm = withHandleChange(LoginForm);
const LoginBox = props => (
<div className="login-box">
<WrappedLoginForm />
</div>
);
这是有效的实现吗?我主要关心的两个问题是(1)将状态作为WrappedComponent
定义中的withHandleChange
的支持,以及(2)渲染WrappedLoginForm
,因为我读过您不应该在render方法内使用HOC。
至于(1),这有效吗?有没有更好的方法来完成我的工作?
关于(2),我认为他们的意思是我不应该在render方法中运行HOC function,而只需使用包装的组件(就像我现在所做的那样)就可以了。但是,我有点困惑,希望能得到一些确认。
任何建议都将有所帮助。谢谢!
由于下面的表达式,不允许在渲染生命周期中使用HOC
const WrappedLoginForm = withHandleChange(LoginForm);
声明了一个组件。而且您知道渲染生命周期可能会执行多次,这取决于您的应用程序到底发生了什么。这样一来,被包装的组件的声明将被执行,这可能会导致意外的行为。我认为这是不允许使用此功能的根本原因。