如何将 reduxForm() 和 connect() 一起用于反应中的 class 组件?
How to use reduxForm() and connect() together for class component in react?
在 reducer 文件中添加了 reducer
const reducers = {
// ... other reducers here ...
form: formReducer
};
我正在使用 redux-form
v 7.1.2 和 react v 16,并使用在此 class 中应用的 reduxForm()`` but there is already
connect()`,尝试了 2 次尝试将两个 HOC 添加到同一页面,但都失败了。
下面是我的文件的相关代码,请检查并告诉我缺少什么?
- 使用命名导出
renderField.jsx
import React from 'react';
const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} placeholder={label} type={type} />
{touched && error && <span>{error}</span>}
</div>
</div>
);
export default renderField;
Register.jsx
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import { renderField } from './renderField';
class RegisterPage extends React.Component {
constructor (props) {
super(props);
this.state = {
user: {
firstName: ''
},
submitted: false
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit (values) {
this.setState({ submitted: true });
const { user } = this.state;
const { dispatch } = this.props;
dispatch(userActions.register(user));
}
render () {
const { registering } = this.props;
return (
<div className="col-md-6 col-md-offset-3">
<h2>Register</h2>
<form onSubmit={this.handleSubmit} >
<div className="form-group">
<Field
name="firstName"
type="text"
label="First Name"
className="form-control"
component={renderField}
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary" disabled={this.pristine} >Register</button>
{ registering && <Loading /> }
<Link to="/login" className="btn btn-link">Cancel</Link>
</div>
</form>
</div>
);
}
}
下面class定义,这里是connect和reduxForm的用法
RegisterPage = reduxForm({
form: 'register',
destroyOnUnmount: false
})(RegisterPage);
const connectedRegisterPage = connect(mapStateToProps)(RegisterPage);
export { connectedRegisterPage as RegisterPage };
App.jsx
import { RegisterPage } from '../RegisterPage';
<Route path="/register" component={RegisterPage} />
但是这会在控制台中给出多个警告
Failed prop type: The prop component
is marked as required in
Field
, but its value is undefined
. in Field (created by
RegisterPage)
Warning: React.createElement: type is invalid -- expected a string
(for built-in components) or a class/function (for composite
components) but got: undefined. You likely forgot to export your
component from the file it's defined in. Check the render method of
ConnectedField
.
- 默认导出
Register.jsx
RegisterPage = reduxForm({
form: 'register'
})(RegisterPage);
const connectedRegisterPage = connect(mapStateToProps)(RegisterPage);
export { connectedRegisterPage as default };
App.jsx
import RegisterPage from '../RegisterPage';
console.log("RegisterPage", RegisterPage); // undefined
这不会给出警告,但会在浏览器中显示空白页
您已将 renderField
导出为 default
和 imported as a named import
。更正它,它应该可以正常工作
import React from 'react';
const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} placeholder={label} type={type} />
{touched && error && <span>{error}</span>}
</div>
</div>
);
export {renderField};
在 reducer 文件中添加了 reducer
const reducers = {
// ... other reducers here ...
form: formReducer
};
我正在使用 redux-form
v 7.1.2 和 react v 16,并使用在此 class 中应用的 reduxForm()`` but there is already
connect()`,尝试了 2 次尝试将两个 HOC 添加到同一页面,但都失败了。
下面是我的文件的相关代码,请检查并告诉我缺少什么?
- 使用命名导出
renderField.jsx
import React from 'react';
const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} placeholder={label} type={type} />
{touched && error && <span>{error}</span>}
</div>
</div>
);
export default renderField;
Register.jsx
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import { renderField } from './renderField';
class RegisterPage extends React.Component {
constructor (props) {
super(props);
this.state = {
user: {
firstName: ''
},
submitted: false
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit (values) {
this.setState({ submitted: true });
const { user } = this.state;
const { dispatch } = this.props;
dispatch(userActions.register(user));
}
render () {
const { registering } = this.props;
return (
<div className="col-md-6 col-md-offset-3">
<h2>Register</h2>
<form onSubmit={this.handleSubmit} >
<div className="form-group">
<Field
name="firstName"
type="text"
label="First Name"
className="form-control"
component={renderField}
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary" disabled={this.pristine} >Register</button>
{ registering && <Loading /> }
<Link to="/login" className="btn btn-link">Cancel</Link>
</div>
</form>
</div>
);
}
}
下面class定义,这里是connect和reduxForm的用法
RegisterPage = reduxForm({
form: 'register',
destroyOnUnmount: false
})(RegisterPage);
const connectedRegisterPage = connect(mapStateToProps)(RegisterPage);
export { connectedRegisterPage as RegisterPage };
App.jsx
import { RegisterPage } from '../RegisterPage';
<Route path="/register" component={RegisterPage} />
但是这会在控制台中给出多个警告
Failed prop type: The prop
component
is marked as required inField
, but its value isundefined
. in Field (created by RegisterPage)Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in. Check the render method of
ConnectedField
.
- 默认导出
Register.jsx
RegisterPage = reduxForm({
form: 'register'
})(RegisterPage);
const connectedRegisterPage = connect(mapStateToProps)(RegisterPage);
export { connectedRegisterPage as default };
App.jsx
import RegisterPage from '../RegisterPage';
console.log("RegisterPage", RegisterPage); // undefined
这不会给出警告,但会在浏览器中显示空白页
您已将 renderField
导出为 default
和 imported as a named import
。更正它,它应该可以正常工作
import React from 'react';
const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} placeholder={label} type={type} />
{touched && error && <span>{error}</span>}
</div>
</div>
);
export {renderField};