#javascript #reactjs
Вопрос:
Цель:
При нажатии на кнопку имя и фамилия из выбранной строки будут отображаться в модальном режиме. Вы должны разрешить повторное использование содержимого и кода одного и того же модала.
Проблема:
Я не знаю, как ее решить, и чего мне не хватает для достижения цели?
Информация:
*Я новичок в ReactJS
Стакблитц:
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;
}
Комментарии:
1. В настоящее время вы не сохраняете свое имя и фамилию в штате. Установите его так же, как вы делаете с modalIsOpen. Затем попробуйте показать это внутри вашего модального имени, например, Имя: {this.state.FirstName}.
Ответ №1:
Я бы рекомендовал на самом деле сделать контент динамичным. Это позволит вам легко получить доступ к этим данным.
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' }
]
};
Затем визуализируйте его с помощью:
<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>;
Вы также можете напрямую хранить открытый элемент вместо индекса. Это, вероятно, позволило бы избежать некоторых ошибок состояния.
Клавиша
Теперь вам понадобится ключ, чтобы в случае изменения массива react знал, какой элемент был удален/добавлен. Этот ключ должен быть уникальным в массиве. Так что в этом случае вполне вероятно, что у вас будет какой-то идентификатор пользователя, но я решил добавить в массив свойство ключа, которое напоминает имя пользователя для входа (для чего угодно).
Подробнее о ключах читайте здесь: https://reactjs.org/docs/lists-and-keys.html#keys
Функции со стрелками вместо методов
Я также взял на себя смелость преобразовать ваши привязки this в атрибуты с функциями стрелок. Таким образом, контекст всегда такой. Взгляните на это.
Стекблитц с индексом:
https://stackblitz.com/edit/reactjs-part1-hello-world-58yys2?file=index.js
Стекблитц с товаром:
https://stackblitz.com/edit/reactjs-part1-hello-world-27rr7b
Ответ №2:
Поместите своих пользователей в состояния:
users: [
{ fname: 'a', lname: 'b' },
{ fname: 'c', lname: 'd' },
{ fname: 'f', lname: 'e' }
]
И в вашей таблице вы можете использовать карту, но сначала проверьте, установлена ли она, если ваши данные из состояния:
{this.state.users !== "undefined" amp;amp;
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
Комментарии:
1. На самом деле вам бы это не понадобилось
typeof
. Просто сравните сundefined
прямым2. Ах, вы правы. Спасибо. Я также должен изменить ключ для tr на индекс.
3. Я бы настоятельно рекомендовал не использовать индекс (но на самом деле я вообще забыл включить индекс в свой ответ lol [добавил его сейчас]). reactjs.org/docs/lists-and-keys.html#keys Обратите внимание, как они указывают последнее средство 🙂
4. Да, я всегда использую идентификаторы своих данных в качестве ключей. Я часто использую
[ID1: {key1: value1, key2: value2}...]
как часть возвращаемых данных из своего API.