简体   繁体   中英

How to show the selected row in the modal

Goal:
When you press on the button, the first and last name from the selected row shall display in the modal. You should enable to reuse the same modal's content and code.

Problem:
I do not know how to solve it and part am I missing in order to achieve the goal?

Info:
*I'm new in ReactJS

Stackblitz:
https://stackblitz.com/edit/reactjs-part1-hello-world-xu6up2?file=style.css


import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import Modal from 'react-modal';

class App extends Component {
  constructor() {
    super();

    this.state = {
      modalIsOpen: false
    };

    this.handleOpenModal = this.handleOpenModal.bind(this);
    this.handleCloseModal = this.handleCloseModal.bind(this);
  }

  handleOpenModal() {
    this.setState({ isModalOpen: true });
  }

  handleCloseModal() {
    this.setState({ isModalOpen: false });
  }

  render() {
    return (
      <div>
        <table border="1">
          <thead>
            <tr>
              <th>First Name</th>
              <th>Last Name</th>
              <th />
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Josef</td>
              <td>Andersson</td>
              <td>
                <button onClick={this.handleOpenModal}>Open Modal</button>
              </td>
            </tr>
            <tr>
              <td>Jim</td>
              <td>West</td>
              <td>
                <button onClick={this.handleOpenModal}>Open Modal</button>
              </td>
            </tr>
            <tr>
              <td>Joe</td>
              <td>West</td>
              <td>
                <button onClick={this.handleOpenModal}>Open Modal</button>
              </td>
            </tr>
          </tbody>
        </table>

        <div>
          <Modal className="confirmation-modal" isOpen={this.state.isModalOpen}>
            First Name: <br />
            Last Name: <br />
            <br />
            <button onClick={this.handleCloseModal}>Close Modal</button>
          </Modal>
        </div>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

h1,
p {
  font-family: Lato;
}

.confirmation-overlay.ReactModal__Overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
  background-color: rgba(0, 0, 0, 0.6);
}

.confirmation-overlay.ReactModal__Overlay--after-open {
  opacity: 1;

  transition: opacity 300ms ease-out;
}

.confirmation-modal.ReactModal__Content {
  position: absolute;

  top: 25%;
  left: 50%;
  width: 500px;
  right: auto;
  bottom: auto;
  border: 1px solid #eee;
  margin-right: -50%;
  transform: scale(0);
  background-color: #fff;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  outline: none;
  padding: 20px;
  opacity: 0;
}

.confirmation-modal.ReactModal__Content--after-open {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  transition: all 300ms ease-out;
}

.confirmation-modal button {
  border: 1px solid black;
  background-color: #fff;
  color: #333;
  padding: 4px 8px;
  margin: 4px;
  border-radius: 3px;
  cursor: pointer;
}

.confirmation-modal button:hover {
  background-color: #eee;
}

I would recommend actually making the content dynamic. That will enable you to easily access that data.

this.state = {
  modalOpenWith: null,
  items: [
    { firstName: 'Josef', lastName: 'Anderson', key: 'josef.anderson' },
    { firstName: 'Jim', lastName: 'West', key: 'jim.west' },
    { firstName: 'Joe', lastName: 'West', key: 'joe.west' }
  ]
};

Then render it with:

<tbody>
  {items.map(({ firstName, lastName, key }, i) => (
    <tr key={key}>
      <td>{firstName}</td>
      <td>{lastName}</td>
      <td>
        <button onClick={() => this.handleOpenModal(i)}>Open Modal</button>
      </td>
    </tr>
  ))}
</tbody>;

You could also directly store the open item instead of the index. That would probably avoid some state errors.

Key

You will now need a key so in case the array changes, react knows which item was removed/added. This key has to be unique in the array. So in that case it sounds likely that you would have a user id of some sort, but I opted to add a key property to the array that resembles a username to login (to whatever).

Read more about keys here: https://reactjs.org/docs/lists-and-keys.html#keys

Arrow functions instead of methods

I also took the liberty to convert your this binds, to attributes with arrow functions. That way the context is always this. Take a look at it.

Stackblitz with index:

https://stackblitz.com/edit/reactjs-part1-hello-world-58yys2?file=index.js

Stackblitz with item:

https://stackblitz.com/edit/reactjs-part1-hello-world-27rr7b

Put your users in states:

users: [
    { fname: 'a', lname: 'b' },
    { fname: 'c', lname: 'd' },
    { fname: 'f', lname: 'e' }
  ]

And in your table you can use map, but check if it is set first if your data is from a state:

{this.state.users !== "undefined" &&
          this.state.users.map((user, index) => {
            const { fname, lname } = user; //destructuring
            return (
              <tr key={index}>
                <td>{fname}</td>
                <td>{lname}</td>
                <td>
                  <button
                    onClick={() => this.handleOpenModal(fname, lname)}
                  >
                    Open Modal
                  </button>
                </td>
              </tr>
            );
          })}

https://stackblitz.com/edit/reactjs-part1-hello-world-grvypp?file=index.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM