Как визуализировать компонент onClick с помощью кнопки в другом компоненте? - PullRequest
0 голосов
/ 28 мая 2020

Я пытаюсь визуализировать компонент с помощью кнопки «Редактировать» внутри компонента. Я решил использовать в своем коде условный рендеринг, но не могу заставить его работать должным образом. Есть ли у кого-нибудь идеи, как мне добиться такого результата? Я чувствую, что приближаюсь к прорыву, но я не знаю, что мне не хватает.

ClientTable. js

import React, { Component } from "react";
import { Table, Container, Button } from "reactstrap";
import { connect } from "react-redux";
import {
  getClients,
  addClient,
  deleteClient,
  setClientToEdit,
} from "../actions/clientActions";
import PropTypes from "prop-types";
import ClientEditModal from "./ClientEditModal";

class ClientTable extends Component {
  state = {
    isOpen: false,
  };

  componentDidMount() {
    this.props.getClients();
  }

  openEditModal = () => {
    if (this.state.isOpen === false) {
      return <ClientEditModal />;
    } else {
      return null;
    }
  };

  onDeleteClick = (id) => {
    this.props.deleteClient(id);
  };

  renderClient = (clients, _id) => {
    return (
      <tr key={_id} timeout={500} classNames="fade">
        <td>
          <Button
            className="remove-btn"
            color="danger"
            size="sm"
            onClick={() => this.onDeleteClick(clients._id)}
          >
            &times;
          </Button>

          <Button
            style={{ marginLeft: ".2rem" }}
            className="add-btn"
            outline
            color="warning"
            size="sm"
            onClick={this.openEditModal}
          >
            Edit
          </Button>

          <Button
            style={{ marginLeft: ".3rem" }}
            className="detail-btn"
            outline
            color="info"
            size="sm"
            onClick={this.toggleDetails}
          >
            Details
          </Button>
        </td>
        <td>{clients.name}</td>
        <td>{clients.email}</td>
        <td>{clients.number}</td>
      </tr>
    );
  };

  render() {
    const { clients } = this.props.client;
    return (
      <Container id="listContainer">
        <Table
          id="listTable"
          className="table-striped table-bordered table-hover"
          dark
        >
          <tr class="listRow">
            <thead id="tableHeader">
              <tr>
                <th id="listActions">Actions</th>
                <th id="listName">Name</th>
                <th id="listEmail">Email</th>
                <th id="listNumber">Number</th>
              </tr>
            </thead>
            <tbody class="listRow">{clients.map(this.renderClient)}</tbody>
          </tr>
        </Table>
      </Container>
    );
  }
}

ClientTable.propTypes = {
  getClients: PropTypes.func.isRequired,
  client: PropTypes.object.isRequired,
};

const mapStateToProps = (state) => ({
  client: state.client,
});

export default connect(mapStateToProps, {
  getClients,
  deleteClient,
  addClient,
  setClientToEdit,
})(ClientTable);

ClientEditModal. js

import React, { Component } from "react";
import {
  Button,
  Modal,
  ModalHeader,
  ModalBody,
  Form,
  FormGroup,
  Label,
  Input,
} from "reactstrap";
import { connect } from "react-redux";
import { editClient } from "../actions/clientActions";
import PropTypes from "prop-types";

class ClientEditModal extends Component {
  state = {
    modal: false,
  };

  componentDidMount() {
    this.props.editClient();
  }

  toggle = () => {
    this.setState({
      modal: !this.state.modal,
    });
  };

  onChange = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  };

  onSubmit = (e) => {
    e.preventDefault();

    // Close modal
    this.toggle();
  };

  render() {
    const { clients } = this.props.client;
    return (
      // Split button into separate component
      <div>
        <Modal isOpen={this.state.modal} toggle={this.toggle}>
          <ModalHeader toggle={this.toggle}> Edit</ModalHeader>

          <ModalBody>
            <Form onSubmit={this.onSubmit}>
              <FormGroup>
                <Label for="name"> Name </Label>
                <Input
                  type="text"
                  name="name"
                  id="client"
                  value={clients.name}
                  onChange={this.onChange}
                ></Input>
                <Label for="email"> Email </Label>
                <Input
                  type="text"
                  name="email"
                  id="client"
                  value={clients.email}
                  onChange={this.onChange}
                ></Input>
                <Label for="number"> Number </Label>
                <Input
                  type="text"
                  name="number"
                  id="number"
                  value={clients.number}
                  onChange={this.onChange}
                ></Input>
                <Button color="dark" style={{ marginTop: "2rem" }} block>
                  Submit Client Edit
                </Button>
              </FormGroup>
            </Form>
          </ModalBody>
        </Modal>
      </div>
    );
  }
}

ClientEditModal.propTypes = {
  editClient: PropTypes.func.isRequired,
  client: PropTypes.object.isRequired,
};

const mapStateToProps = (state) => ({
  client: state.client,
});

export default connect(mapStateToProps, { editClient })(ClientEditModal);

1 Ответ

0 голосов
/ 28 мая 2020

onClick не может вернуть компонент, что не имеет смысла.

В onClick вы должны установить состояние. И в рендере вам нужно проверить состояние и отобразить компонент

, например:

{this.state.isOpen ? <ClientEditModal /> : null}

, и ваша функция openEditModal будет выглядеть так

openEditModal = () => {
    if (this.state.isOpen === false) {
      this.setState({isOpen: true})
    } 
  };

Ваш clientTable.jsx будет иметь вид

import React, { Component } from "react";
import { Table, Container, Button } from "reactstrap";
import { connect } from "react-redux";
import {
  getClients,
  addClient,
  deleteClient,
  setClientToEdit,
} from "../actions/clientActions";
import PropTypes from "prop-types";
import ClientEditModal from "./ClientEditModal";

class ClientTable extends Component {
  state = {
    isOpen: false,
  };

  componentDidMount() {
    this.props.getClients();
  }

  openEditModal = () => {
    if (this.state.isOpen === false) {
      this.setState({isOpen: true})
    } 
  };

  onDeleteClick = (id) => {
    this.props.deleteClient(id);
  };

  renderClient = (clients, _id) => {
    return (
      <tr key={_id} timeout={500} classNames="fade">
        <td>
          <Button
            className="remove-btn"
            color="danger"
            size="sm"
            onClick={() => this.onDeleteClick(clients._id)}
          >
            &times;
          </Button>

          <Button
            style={{ marginLeft: ".2rem" }}
            className="add-btn"
            outline
            color="warning"
            size="sm"
            onClick={this.openEditModal}
          >
            Edit
          </Button>

          <Button
            style={{ marginLeft: ".3rem" }}
            className="detail-btn"
            outline
            color="info"
            size="sm"
            onClick={this.toggleDetails}
          >
            Details
          </Button>
        </td>
        <td>{clients.name}</td>
        <td>{clients.email}</td>
        <td>{clients.number}</td>
      </tr>
    );
  };

  render() {
    const { clients } = this.props.client;
    return (
      <Container id="listContainer">
        {this.state.isOpen ? <ClientEditModal /> : null };
        <Table
          id="listTable"
          className="table-striped table-bordered table-hover"
          dark
        >
          <tr class="listRow">
            <thead id="tableHeader">
              <tr>
                <th id="listActions">Actions</th>
                <th id="listName">Name</th>
                <th id="listEmail">Email</th>
                <th id="listNumber">Number</th>
              </tr>
            </thead>
            <tbody class="listRow">{clients.map(this.renderClient)}</tbody>
          </tr>
        </Table>
      </Container>
    );
  }
}

ClientTable.propTypes = {
  getClients: PropTypes.func.isRequired,
  client: PropTypes.object.isRequired,
};

const mapStateToProps = (state) => ({
  client: state.client,
});

export default connect(mapStateToProps, {
  getClients,
  deleteClient,
  addClient,
  setClientToEdit,
})(ClientTable);
...