Как передать данные из компонента, по которому щелкнули мышью, из одного маршрута в другой в React?

Я работаю над приложением для поиска видеоигр, которое извлекает данные из GiantBomb API с помощью React Router. Когда поиск выполняется в компоненте SearchGames, он возвращает список игр из API через компонент Game. На чем я застрял, так это на том, чтобы выяснить, как передать детали данных указанной игры, которую вы нажимаете, компоненту GamesDetail с помощью Router. Я не думаю, что смогу сделать это с помощью props, поскольку отдельное представление со всеми деталями не является ни родительским, ни дочерним компонентом. Я надеюсь, что то, о чем я прошу, имеет смысл.

class App extends Component {
  render() {
    return (
      <Router>
        <div className = "App">
          <Nav />
          <div className = "container">
            <Switch>
              <Route exact path = "/" component = {MainPage} />
              <Route exact path = "/games" component = {GameSearch} />
              <Route exact path = "/about" component = {About} />}
              <Route exact path = "/details" component = {GamesDetails} />}
            </Switch>
          </div>
        </div>
      </Router>
    );
  }
}

class Search extends Component {
      constructor(props) {
        super(props);
        this.state = {
          title: "",
          games: []
        }
      }

  updateInput = (event) => {
    this.setState({
      title: event.target.value
    });
  }

  handleGames = (search) => {
    const proxyUrl = "https://cors-anywhere.herokuapp.com/";
    const key = "8cd10a7136710c1003c8e216d85941ace5a1f00e";
    const endpoint = `https://www.giantbomb.com/api/search/?api_key=`;
    const url = proxyUrl + endpoint + key + `&format=json&resources=game&query=${search}&limit=30`;

    fetch(url)
      .then(res => res.json())
      .then(data => {
        const response = data.results;
        console.info(response);
        response.forEach(game => {
          this.setState(prevState => ({
            games: prevState.games.concat(game)
          }))
        });
      });

    this.setState({
      games: []
    })

  }

  handleSubmit = (e) => {
    const { title } = this.state;

    e.preventDefault();

    if (!title) {
      return;
    } else {
      this.handleGames(title);
    }

  }

  render() {
    const { games } = this.state;
    return (

      <div className = "App">
        <div className = "search-bar">
          <form>
            <input
              className = "input-field"
              type = "text"
              placeholder = "Search Game"
              onChange = {this.updateInput}
            />
            <button
              className = "search-button"
              onClick = {this.handleSubmit}
            >Search</button>
          </form>
        </div>
        <div className = "container">
          {games.length > 0 ? (
            games.map(game => {
              return <Game
                key = {game.id}
                icon = {game.image.icon_url}
                gameTitle = {game.name}
              />
            })
          ) : (
              console.info(this.state.title)
            )
          }


        </div>
      </div>

    );
  }
}

const Game = (props) => {
  const { icon, gameTitle } = props;
  return (
    <div className = "games-container">
      <div className = "game-box">
        <img src = {icon} alt = "icon" />
        <Link to = "/details">
          <p><strong>{gameTitle}</strong></p>
        </Link>
      </div>
    </div>
  );
}

const GameDetails = (props) => {
  const { icon, release, genres, summary} = props;
  return (
    <div className = "details-content">
      <div className = "box-art">
        <img src = {icon} alt = "box art" />
      </div>
      <div className = "game-info">
        <h1>Game Details</h1>
        <div className = "release-date">
          <h3>Release Data</h3>
          <p>{release}</p>
        </div>
        <div className = "genres">
          <h3>Genres</h3>
          <p>{.genres}</p>
        </div>
        <div className = "summary">
          <h3>Summary</h3>
          <p>{summary}</p>
        </div>
      </div>
    </div>
  );
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны иметь возможность достичь этого, используя Link с to в качестве объект, который предоставляет state, который может быть передан в результирующий Route:

// ...
// pass game object to Game component
// if you are passing game, you probably don't need other props explicitly passed
{games.length > 0 ? (
  games.map(game => {
    return <Game
      key = {game.id}
      game = {game}
      icon = {game.image.icon_url}
      gameTitle = {game.name}
    />
  })
 ) : (
   console.info(this.state.title)
 )
}

// ...

const Game = (props) => {
  const { icon, gameTitle, game } = props;

  return (
    <div className = "games-container">
      <div className = "game-box">
        <img src = {icon} alt = "icon" />
        <Link to = {{ pathname: "/details", state: { game } }}>
          <p><strong>{gameTitle}</strong></p>
        </Link>
      </div>
    </div>
  );
}

Затем вы можете получить доступ к этому state из опоры место нахождения, которую react-router-dom вводит в props:

const GamesDetails = (props) => {
  const { image: { icon_url: icon }, release, genres, summary } = props.location.state.game;

  return (
    <div className = "details-content">
      <div className = "game-info">
        <h1>Game Details</h1>
        <div className = "box-art">
          <img src = {icon} alt = "box art" />
        </div>
        <div className = "release-date">
          <h3>Release Data</h3>
          <p>{release}</p>
        </div>
        <div className = "genres">
          <h3>Genres</h3>
          <p>{genres}</p>
        </div>
        <div className = "summary">
          <h3>Summary</h3>
          <p>{summary}</p>
        </div>
      </div>
    </div>
  );
}

Вот пример в действии.

Надеюсь, это поможет!

Вау, спасибо большое! В этом гораздо больше смысла, и это работает как шарм. Очень признателен!

envincebal 10.11.2018 04:18

Другие вопросы по теме