Разъяснение о наследовании React - PullRequest
0 голосов
/ 12 июня 2019

У меня есть один случай наследования в React: один модуль User, который имеет компоненты UserList и UserForm со своими собственными функциями, такими как отображение списка пользователей в компоненте UserList и отправка формы в UserForm.В корне проекта / библиотеки также есть свои действия-редукторы.Теперь я хотел бы использовать этот компонент в нескольких приложениях.Какой лучший вариант в React?Что я уже пробовал в отношении наследования:

  1. Созданный модуль Core включает компонент User (UserList, UserCreat / Edit).
  2. Включить этот модуль ядра в Project1 >> Src
  3. Расширьте его, переписав 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 для расширения ее функциональности и пользовательского интерфейса

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));

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...