@Kerhin

Как скопировать данные из 1 элемента в другой в React?

Есть проблема с копированием данных из одного элемента в другой.

Есть ряд одинаковых блоков с классом .writer. И 2 блока для вывода данных .dataWriter и .dataBooks. Так вот, задача заключается в том, что я хотел бы при клике по любому из блоков с классом .writer распределять его данные по тем 2-м блокам.
В блок .dataWriter вносились бы данные о самом писателе (указанные текстом), а в блок .dataBooks вносилась полная структура DOM элементов блока с классом .booksWrap (как по типу innerHTML).
Ну и когда происходит клик по .writer, то ему присваивался класс .active, а если вы кликните по другому блоку .writer, то у прошлого удалиться .active, а новому присвоится. Тоже самое и сданными блоков.

5cf441357ed4a163703974.png

Ниже я опишу чуть более подробный сценарий действия функции.
Вот сам код. Думаю на верстку нет никакого смысла обращать свое внимание, но я все-равно прикреплю ее.
Там сначала идет крупный ассоциативный массив, не пугайтесь, он лишь кажется большим и неразборчивым. (Он состоит из Разных веков => Живших в то время писателей => И их книг).

const writersData = {
	'19 век': {
		'Лев Николаевич Толстой': {
			country: 'Российская империя',
			quote: 'Старость — самая большая неожиданность в жизни',
			born: '1828',
			died: '1910',
			books: {
				'Анна Каренина': {
					genre: 'Роман',
					dateWritten: '1877'
				},
				'Война и мир': {
					genre: 'Роман',
					dateWritten: '1869'
				},
				'Кавказский пленник': {
					genre: 'Рассказ',
					dateWritten: '1872'
				}
			}
		},
		'Николай Васильевич Гоголь': {
			country: 'Российская империя',
			quote: 'Чуден Днепр при тихой погоде, когда вольно и плавно мчит сквозь леса и горы полные воды свои',
			born: '1809',
			died: '1852',
			books: {
				'Вий': {
					genre: 'Повесть',
					dateWritten: '1833'
				},
				'Мёртвые души': {
					genre: 'Поэма',
					dateWritten: '1835'
				},
				'Записки сумасшедшего': {
					genre: 'Повесть',
					dateWritten: '1834'
				},
				'Тарас Бульба': {
					genre: 'Повесть',
					dateWritten: '1835'
				}
			}
		}
	},
	'18 век': {
		'Михаил Васильевич Ломоносов': {
			country: 'Российское царство',
			quote: 'Легко быть философом, выучась наизусть три слова: Бог так сотворил; и сие дая в ответ вместо всех причин',
			born: '1711',
			died: '1765',
			books: {
				'Введение в истинную физическую химию': {
					genre: 'Рукопись',
					dateWritten: '1752'
				},
				'Ода на взятие Хотина': {
					genre: 'Ода',
					dateWritten: '1739'
				}
			}
		},
		'Державин Гавриил Романович': {
			country: 'Российская империя',
			quote: 'Самое лучшее предназначение есть защищать свое отечество',
			born: '1743',
			died: '1816',
			books: {
				'Памятник': {
					genre: 'Стихотворение',
					dateWritten: '1795'
				},
				'Водопад': {
					genre: 'Поэзия',
					dateWritten: '1794'
				},
				'Глагол времен': {
					genre: 'Поэзия',
					dateWritten: '1779'
				}
			}
		},
		'Радищев Александр Николаевич': {
			country: 'Российская империя',
			quote: 'Блеск наружный может заржаветь, но истинная красота не поблекнет никогда',
			born: '1749',
			died: '1802',
			books: {
				'Путешествие из Петербурга в Москву': {
					genre: 'Повесть',
					dateWritten: '1790'
				}
			}
		}
	}
}

function Book(props) {
	return(
		<div className="book">
			<h4 className="book__name">{props.name}</h4>
			<p className="book__genre">Жанр: {props.genre}</p>
			<p className="book__dateWritten">Дата написания: {props.dateWritten}</p>
		</div>
	);
}

function Writer(props) {
	return(
		<div className="writer">
			<h3 className="writer__name">{props.name}</h3>
			<p className="writer__yearsLife">{props.born} - {props.died}</p>
			<p className="writer__country">{props.country}</p>
			<p className="writer__quote">{props.quote}</p>
			<div className="booksWrap">
				{Object.entries(props.books).map(([ i, j ]) => (
					<Book key={i} name={i} {...j} />
				))}
			</div>
		</div>
	);
}

function Century(props) {
	return(
		<div className="century">
			<div className="centuryTitle">
				<h2 className="centuryTitle__name">{props.name}</h2>
			</div>
			{Object.entries(props.writers).map(([ i, j ]) => (
				<Writer key={i} name={i} {...j} />
			))}
		</div>
	);
}

function OutDataWriter() {
	return(
		<div className="dataWriter">
			<h1 className="dataWriter__title">Вывод данных о писателе</h1>
			<p className="dataWriter__data">Имя писателя: </p>
			<p className="dataWriter__data">Годы жизни: </p>
			<p className="dataWriter__data">Место рождения: </p>
			<p className="dataWriter__data">Цитата: </p>
		</div>
	);
}

function OutDataBooks() {
	return(
		<div className="dataBooks">
			<h1 className="dataBooks__title">Вывод книг</h1>
		</div>
	);
}

function App(props) {
	return(
		<div className="container">
			{Object.entries(props.centuries).map(([ i, j ]) => (
				<Century key={i} name={i} writers={j} />
			))}
			<OutDataWriter />
			<OutDataBooks />
		</div>
	);
}

ReactDOM.render(
	<App centuries={writersData} />,
	document.getElementById('root')
);


* {
	margin: 0;
	padding: 0;
}
.container {
	width: 100%;
	height: 100vh;
	background-color: #1f1f1f;
}
.century {
	position: relative;
	display: block;
	float: left;
	width: 500px;
	height: 100%;
	/*border: 1px solid #cfc8b7;*/
	border: 1.5px solid #5d5b53;
	border-left: 0px;
	overflow: scroll;
}
.centuryTitle {
	position: fixed;
	bottom: 0;
	width: 500px;
	height: 50px;
	background-color: #1f1f1f;
}
.centuryTitle__name {
	text-align: center;
	font-family: sans-serif;
	font-size: 16px;
	font-weight: 100;
	color: #c5beae;
}

.writer {
	padding: 10px 5px;
	margin-bottom: 30px;
	border-bottom: 1.5px solid #5d5b53;
}
.writer__name,
.writer__country,
.writer__quote,
.writer__yearsLife {
	margin: 5px 0;
	text-align: center;
	font-family: sans-serif;
	font-weight: 400;
	color: #c5beae;
	font-size: 12px;
}
.writer__name {
	font-size: 24px;
}
.writer__yearsLife {
	font-size: 18px;
}

.booksWrap {
	border: 1.5px solid #5d5b53;
}
.book {
	border: 1.5px solid #5d5b53;
	margin: 5px;
}
.book__name,
.book__genre,
.book__dateWritten {
	text-align: center;
	font-family: sans-serif;
	font-weight: 400;
	color: #c5beae;
	font-size: 12px;
}
.book__name {
	font-size: 16px;
	font-weight: 500;
}

.dataWriter,
.dataBooks {
	width: 300px;
	display: block;
	float: left;
	border: 1.5px solid #5d5b53;
}
.dataWriter__title,
.dataBooks__title {
	margin: 5px 0;
	text-align: center;
	font-family: sans-serif;
	font-weight: 400;
	color: #c5beae;
	font-size: 24px;
}
.dataWriter__data {
	margin: 5px 0;
	font-family: sans-serif;
	font-weight: 400;
	color: #c5beae;
	font-size: 12px;
}

.active {
	background-color: #808080;
}


Сценарий:
Выше приведена скрин данного веб-приложения. Предположим я хочу в 2 крайних маленьких блока .dataWriter и .dataBooks вывести информацию о Ломоносове. Я кликаю по его блоку (у блока класс .writer), он присваивает ему класс .active, блок выделился серым цветом. Так же параллельно с этим письменные данные (имя, год рождения и смерти, место рождения, цитата) копируются в блок .dataWriter. А блок с классом .booksWrap хранящий в себе книги писателей, который обведен зеленой границей полностью копируется в .dataBooks со всей структурой DOM элементов (как это делало бы свойство innerHTML).
А потом, я допустим захотел вывести данные о Гоголе вместо Ломоносова. Я кликаю по блоку Гоголя (который так же имеет класс .writer), с блока Ломоносова снимается все выделение (удаляется класс .active), в те 2 крайних блока теперь заносится информация о Гоголе вместо Ломоносова (удаляя информацию о Ломоносове).

5cf44a43611a0623828952.png
  • Вопрос задан
  • 349 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Передавайте в компонент списка обработчик клика, который будет данные кликнутого элемента сохранять. Эти сохранённые данные передавайте в компонент, где надо продублировать информацию. Как-то так.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы