Я работаю над приложением для поиска видеоигр, которое извлекает данные из 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>
);
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы должны иметь возможность достичь этого, используя 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>
);
}
Вот пример в действии.
Надеюсь, это поможет!
Вау, спасибо большое! В этом гораздо больше смысла, и это работает как шарм. Очень признателен!