如何使用另一个组件中的按钮呈现组件 onClick?

Posted

技术标签:

【中文标题】如何使用另一个组件中的按钮呈现组件 onClick?【英文标题】:How to render a component onClick with a button in another component? 【发布时间】:2020-09-16 00:29:45 【问题描述】:

我正在尝试使用组件内的“编辑”按钮来呈现组件。我决定在我的代码中使用条件渲染,但我似乎无法让它正常工作。有人对我如何实现这个结果有任何想法吗?我觉得我快要突破了,但我不知道我错过了什么。

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

【问题讨论】:

你能解释一下你的代码没有什么吗?你能谈谈错误吗? 没有错误。当我单击“编辑”按钮时,它就不起作用了。 你能安排一个codesandbox.io吗? this.setState( [e.target.name]: e.target.value );。这是什么意思? 【参考方案1】:

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

【讨论】:

我这样做了,但仍然无法正常工作。在要渲染的所需组件中我有什么需要更改的吗 也许我应该在我的 App.js 中添加一些东西? 检查this.state.modal是否为真。设置为 true 进行测试。

以上是关于如何使用另一个组件中的按钮呈现组件 onClick?的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应js中更改按钮onClick的背景颜色?

测试按钮单击 ReactJS 上是不是呈现另一个组件

React:从按钮 onclick 传递映射数据以显示在另一个组件上

通过单击另一个组件中的按钮,react-native重新呈现组件

另一个组件中的提交按钮创建辅助功能问题

通过父组件的onClick更新组件状态