我正在开发一个视频游戏搜索应用程序,该应用程序使用React Router从GiantBomb API中获取数据。在SearchGames组件上完成搜索后,它会通过Game组件从API返回游戏列表。我坚持要弄清楚如何使用路由器将单击的列出游戏的数据详细信息传递给GamesDetail组件。我认为我无法使用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.log(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.log(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>
);
}
答案 0 :(得分:1)
您应该能够使用Link
和to
作为object来实现此目的,它公开了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.log(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
的道具location中访问此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>
);
}
这里是example的动作。
希望有帮助!