reactjs - 澄清 React 继承
问题描述
我在 React 中有一个继承案例,即一个模块User
具有组件UserList
并UserForm
具有自己的功能,例如在 UserList 组件中显示 userelist 并在 UserForm 中提交表单。在项目/库的根目录中,它也有自己的动作,reducers。现在我想在多个应用程序中使用这个组件。React 中的最佳选择是什么?到目前为止,我在继承方面所做的尝试:
- 创建的核心模块包括用户(UserList、UserCreat/Edit)组件。
- 在 Project1 >> Src 下包含这个核心模块
- 通过覆盖 Core-UserCreate/Edit Component 来扩展它
但我不确定这是否是一个更好的解决方案。那么有人可以指导我如何以最好的方式实现我的功能吗?
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Form, ButtonToolbar, Col, Row, Button, Alert } from "react-bootstrap";
import _ from 'lodash';
import fields from "./fields.json";
class UserCreateEdit extends Component {
constructor(props) {
super(props);
this.state = {
fields: fields,
label: "",
name: "",
type: "",
placeholder: "",
options: "",
status:false,
title:"Core:New User"
};
[
"_handleSubmit",
"_handleChange",
"_handleFieldsSubmit",
"_handleFieldsChange",
"_handleCancel"
].map((fn) => this[fn] = this[fn].bind(this));
}
static propTypes = {
fields: PropTypes.array
};
_handleSubmit(e) {
e.preventDefault();
const { label, name, type, placeholder, options } = this.state;
this.setState((prevState) => ({
fields: [
...prevState.fields, {
label,
name: name || `name--${prevState.fields.length}`,
type: type || "text",
placeholder,
options
}
]
}));
}
componentDidMount() {
// const { fields, title } = this.props;
// if(!_.isUndefined(fields)){
// this.setState({
// fields:[...fields]
// });
// }
// if(!_.isUndefined(title)){
// this.setState({
// title:[...title]
// });
// }
}
_handleChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
async _handleFieldsSubmit(e) {
e.preventDefault();
console.log("json: ", JSON.stringify(this.state.fields));
const obj = {};
(Object.keys(this.refs) || []).forEach((i) => obj[this.refs[i].name] = this.refs[i].value || "");
console.log('obj: ', obj);
await this.props.saveUser({
user: obj
});
console.log('"status" :', this.props.status);
if(this.props.status){
this.setState({
status: this.state.status
});
this.props.history.push("/users");
}
}
_handleCancel = () => {
this.props.history.push("/users");
}
_handleFieldsChange(e, i) { }
render() {
const fields = (this.state.fields || []).map((f, i) => {
const { label, name, type, value: defaultValue, ...rest } = f;
return (
<Form.Group key={i} controlId={`form--${i}`}>
{(type !== "checkbox" && label) && <Form.Label>{label}</Form.Label>}
{(type === "checkbox") && (
<Form.Check
type={type}
name={`${name}`}
label={label}
defaultValue={defaultValue}
onChange={(e) => this._handleFieldsChange(e, i)}
/>
)}
{(type !== "checkbox" && type !== "select") && (
<Form.Control
type={type}
name={`${name}`}
ref={`form__${name}__${i}`}
defaultValue={defaultValue}
onChange={(e) => this._handleFieldsChange(e, i)}
{...rest}
/>
)}
{(type === "select") && (
<Form.Control
as="select"
name={`${name}`}
ref={`form__${name}__${i}`}
defaultValue={defaultValue}
onChange={(e) => this._handleFieldsChange(e, i)}
>
{(JSON.parse(f.options) || []).map((o) => <option key={o} value={o}>{o}</option>)}
</Form.Control>
)}
</Form.Group>
)
});
return (<div style={{ margin: 20 }}>
<h4>{this.state.title}</h4>
<Form className="mt-3 border-top py-3" onSubmit={this._handleFieldsSubmit} >
{fields}
{((this.state.fields || []).length > 0) && (
<ButtonToolbar>
<Button variant="primary" style={{ marginRight: 10 }} type='submit'>Save</Button>
<Button variant="danger" onClick={ () => this._handleCancel()}>Cancel</Button>
</ButtonToolbar>
)}
</Form>
</div>);
}
}
export default UserCreateEdit;
将 UserCreatEdit 表单继承到 Project1 以扩展其功能和 UI
import React, { Component } from 'react';
import _ from 'lodash';
import { connect } from 'react-redux';
import {UserCreateEdit} from "../../../core";
import { saveUser } from "../../../core";
import { withRouter } from "react-router-dom";
class UserForm extends UserCreateEdit {
constructor(props) {
super(props);
this.state = {
fields: [
...this.state.fields,
{
"label": "Phone",
"name": "phone",
"type": "text",
"placeholder": "Phone",
"options": ""
}
],
title:"Restaurant: New User"
};
}
// render() {
// return (<div style={{ margin: 20 }}>
// <UserCreateEdit fields={this.state.fields} title={'Restaurant: New User'} />
// </div>);
// }
}
const mapStateToProps = state => ({
status: _.get(state, 'users.data.status', [])
});
const mapDispatchToProps = dispatch => ({
saveUser: (payload) => dispatch(saveUser(payload))
});
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(UserForm));
解决方案
推荐阅读
- documentation - 如何创建仅记录通过 index.ts 公开的对象的 Typedoc?
- php - 循环函数(Foreach)Laravel中的处理程序空值
- python - 如何在 PyQt 中通过文本为 QTableView 创建过滤器
- java - Weblogic LogicalConnection 无法强制转换为 oracle.jdbc.OracleConnection
- ios - 在视图出现之前未设置 UIButton 标题
- android - 添加 exoplayer 和打开 java 8 的问题
- c# - C# Sqltimeout 命令不知道程序端还是 sql server 端
- python - 安装不包含测试代码的包
- xml - 当 XSD 和 XML 都被验证时,QXmlSchema 和 QXmlSchemaValidator 给出错误
- php - 使用 Guzzle PHP 循环发送请求多次