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 ?

Route элемента

В качестве "ключа" параметра я пробую ориентироваться на URL книги urlAddress хотя в читаемых примерах постоянно берут id. Я не понимаю, как правильно производить match данных хранимых в state введите сюда описание изображения не получается вывести Имя нажатой книги


Ответы (2 шт):

Автор решения: ivan

Если Вы переходите на другую страницу то может передавать некоторые данные в URL страницы. Обычно это id или slug, забирать их через props.math.params. И основываясь на этих данных отправлять запрос на бэкенд для получения более подробных данных. Но если необходимо передавать полный объект данных то можете посмотреть в сторону context api.

→ Ссылка
Автор решения: BlackStar1991

Вот рабочий пример

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>

Тут рабочая версия задачи

→ Ссылка