React Динамический Роутинг. Как пробросить нужные props в элемент вызова
Подскажите, пожалуйста, как передать нужные значения в новый компонент рендеринга ? Есть такой простой пример
let state = {
booksDescription: [{
id: 1,
bookName: "Понедельник начинается в субботу",
urlAddress: "Monday-starts-on-Saturday",
bookInSection: 1,
authorNumber: 2
},
{
id: 2,
bookName: "Гарри Поттер и Орден Феникса",
urlAddress: "Harry-Potter-and-the-Order-of-the-Phoenix",
bookInSection: 6,
authorNumber: 3
},
{
id: 3,
bookName: "Сказание о трех свинах",
urlAddress: "The-Tale-of-the-Three-Pigs",
bookInSection: 1,
authorNumber: 4
}
],
booksAuthor: [{
id: 1,
authorName: "Борис",
authorSurname: "Стругацкий"
},
{
id: 2,
authorName: "Аркадий",
authorSurname: "Стругацкий"
},
{
id: 3,
authorName: "Джоан",
authorSurname: "Роулинг"
},
{
id: 4,
authorName: "Джон",
authorSurname: "Толкиен"
}
]
};
function Main(props) {
const {
booksDescription,
booksAuthor
} = props;
return (
<
main className = {
"main"
} >
<
Route path = '/'
exact render = {
() => < WorkSpace / >
}
/> <
Route path = '/audio-book/:urlAddress'
render = {
() => < BookArticle
booksDescription = {
booksDescription
}
booksReader = {
booksReader
}
booksAuthor = {
booksAuthor
}
booksCategories = {
booksCategories
}
/>}/ >
<
/main>
);
}
function WorkSpace(props) {
const {
booksDescription,
booksAuthor
} = props;
return ( <
main className = {
"main"
} >
<
div id = "FullListBook" >
<
BookList booksDescription = {
booksDescription
}
booksAuthor = {
booksAuthor
}
/> <
/div> <
/main>
);
}
function BookList(props) {
const {
booksDescription,
booksAuthor
} = props;
let BooksList = booksDescription.map(el => ( <
BookItem id = {
el.id
}
urlAddress = {
el.urlAddress
}
key = {
el.id
}
bookName = {
el.bookName
}
authorNumber = {
el.authorNumber
}
/>
));
return BooksList;
}
class BookItem extends React.Component {
render() {
const book = this.props;
const {
booksReader,
booksAuthor,
} = this.props;
const authorsOfBookNumber = book.authorNumber - 1;
const authorOfBookName = booksAuthor[authorsOfBookNumber].authorName;
const authorOfBookSurname = booksAuthor[authorsOfBookNumber].authorSurname;
const authorsOfBookFull = authorOfBookSurname + " " + authorOfBookName;
return ( <
div className = "bl_book__item" >
<
NavLink className = "bl_book__link"
to = {
"audio-book/" + book.urlAddress
} >
<
p className = "bl_book__name" >
<
p className = "bl_book__title" > {
book.bookName
} < /p> <
p className = "bl_book__author" > {
authorsOfBookFull
} < /p> <
/p> <
/NavLink> <
/div>
);
}
}
function BookArticle(props, match) {
// const {
// booksDescription: {urlAddress}
// } = match;
//
// let bookName = this.props.bookName;
const {
booksDescription,
booksAuthor,
} = this.props;
return ( <
h1 > < /h1>
)
}
import React, {
Component
} from "react";
import {
render
} from "react-dom";
import "./style.css";
import {
BrowserRouter
} from "react-router-dom";
import {
NavLink
} from "react-router-dom";
function App(props) {
return ( <
WorkSpace booksDescription = {
props.state.booksDescription
}
booksAuthor = {
props.state.booksAuthor
}
/>
);
}
render( < BrowserRouter > < App state = {
state
}
/></BrowserRouter > , document.getElementById("root"));
.bl_book__item {
display: inline-block;
width: 150px;
height: 200px;
max-resolution: 40px;
vertical-align: top;
margin-right: 10px;
border: 1px solid #000;
}
article {
padding: 10px;
border: 1px solid #f00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/5.2.0/react-router.min.js"></script>
<div id="root"></div>
Вот более рабочий код *на локалке работал, тут почему-то ещё и ошибку при выводи списка выдает.
Задача простая - Как нажимая на элементы списка книг переходить по ссылке компонента который динамически формируется в Route ?
В качестве "ключа" параметра я пробую ориентироваться на URL книги urlAddress хотя в читаемых примерах постоянно берут id. Я не понимаю, как правильно производить match данных хранимых в state
не получается вывести Имя нажатой книги
Ответы (2 шт):
Если Вы переходите на другую страницу то может передавать некоторые данные в URL страницы. Обычно это id или slug, забирать их через props.math.params. И основываясь на этих данных отправлять запрос на бэкенд для получения более подробных данных. Но если необходимо передавать полный объект данных то можете посмотреть в сторону context api.
Вот рабочий пример
import React, {
Component
} from "react";
import {
render
} from "react-dom";
import {
BrowserRouter
} from "react-router-dom";
import {
NavLink,
Route,
withRouter
} from "react-router-dom";
let state = {
booksDescription: [{
id: 1,
bookName: "Понедельник начинается в субботу",
urlAddress: "Monday-starts-on-Saturday",
bookInSection: 1,
authorNumber: 2
},
{
id: 2,
bookName: "Гарри Поттер и Орден Феникса",
urlAddress: "Harry-Potter-and-the-Order-of-the-Phoenix",
bookInSection: 6,
authorNumber: 3
},
{
id: 3,
bookName: "Сказание о трех свинах",
urlAddress: "The-Tale-of-the-Three-Pigs",
bookInSection: 1,
authorNumber: 4
}
],
booksAuthor: [{
id: 1,
authorName: "Борис",
authorSurname: "Стругацкий"
},
{
id: 2,
authorName: "Аркадий",
authorSurname: "Стругацкий"
},
{
id: 3,
authorName: "Джоан",
authorSurname: "Роулинг"
},
{
id: 4,
authorName: "Джон",
authorSurname: "Толкиен"
}
]
};
function Main(props) {
const {
booksDescription,
booksAuthor
} = props;
return (
<
main className = {
"main"
} >
<
Route path = '/'
exact render = {
() => < WorkSpace booksDescription = {
booksDescription
}
booksAuthor = {
booksAuthor
}
/>}/ >
<
Route path = '/audio-book/:urlAddress'
render = {
() => < BookArticle
booksDescription = {
booksDescription
}
booksAuthor = {
booksAuthor
}
/>}/ >
<
/main>
);
}
function WorkSpace(props) {
const {
booksDescription,
booksAuthor
} = props;
return ( <
main className = {
"main"
} >
<
div id = "FullListBook" >
<
BookList booksDescription = {
booksDescription
}
booksAuthor = {
booksAuthor
}
/> < /
div > <
/main>
);
}
function BookList(props) {
const {
booksDescription,
booksAuthor
} = props;
let BooksList = !booksDescription ? null : booksDescription.map(el => ( <
BookItem id = {
el.id
}
urlAddress = {
el.urlAddress
}
key = {
el.id
}
bookName = {
el.bookName
}
authorNumber = {
el.authorNumber
}
booksAuthor = {
booksAuthor
}
/>
));
return BooksList;
}
class BookItem extends React.Component {
render() {
const book = this.props;
const {
booksReader,
booksAuthor,
} = this.props;
const authorsOfBookNumber = book.authorNumber - 1;
const authorOfBookName = booksAuthor[authorsOfBookNumber].authorName;
const authorOfBookSurname = booksAuthor[authorsOfBookNumber].authorSurname;
const authorsOfBookFull = authorOfBookSurname + " " + authorOfBookName;
return ( <
div className = "bl_book__item" >
<
NavLink className = "bl_book__link"
to = {
"audio-book/" + book.urlAddress
} >
<
p className = "bl_book__name" >
<
p className = "bl_book__title" > {
book.bookName
} < /p> <
p className = "bl_book__author" > {
authorsOfBookFull
} < /p> < /
p > <
/NavLink> < /
div >
);
}
}
const BookArticle = withRouter((props) => {
// const {
// booksDescription: {urlAddress}
// } = match;
//
// let bookName = this.props.bookName;
const {
booksDescription,
booksAuthor,
} = props;
console.log(props)
return ( <
h1 > {
booksDescription.find(book => book.urlAddress === props.match.params.urlAddress).bookName
} < /h1>
)
})
function App(props) {
return ( <
Main booksDescription = {
props.state.booksDescription
}
booksAuthor = {
props.state.booksAuthor
}
/>
);
}
render( < BrowserRouter > < App state = {
state
}
/></BrowserRouter > , document.getElementById("root"));
.bl_book__item {
display: inline-block;
width: 150px;
height: 200px;
max-resolution: 40px;
vertical-align: top;
margin-right: 10px;
border: 1px solid #000;
}
article {
padding: 10px;
border: 1px solid #f00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js" integrity="sha512-FJ5AplytBPxdjAzUUTWdQ8TH/z+uNVH4nBC2KZQpXSUHFmWnPMbqvvEEEqB2Loadbtl5zimK3CQT/MD4IBED+w==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/5.2.0/react-router.min.js" integrity="sha512-sWGrnSIvNDdGRsqnFIm5q1uHjPt5912wNVBK9vChpbHPReP96giWBGeztcd/rva+n82nQLTJ1SFbZqLHbCqMiw==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js" integrity="sha512-FJ5AplytBPxdjAzUUTWdQ8TH/z+uNVH4nBC2KZQpXSUHFmWnPMbqvvEEEqB2Loadbtl5zimK3CQT/MD4IBED+w==" crossorigin="anonymous"></script>
<div id="root"></div>
