Reputation: 1816
I have three js files. The parent I am to call the child classes. The code goes like this.
This is the parent class App.js
import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
import {FirstPage} from './FirstPage.js';
import {Panorama} from './Panorama.js';
import {BrowserRouter,Route,Router,Switch} from 'react-router-dom';
class App extends React.Component{
constructor(props){
super(props);
}
render(){
return(
<div>
<BrowserRouter>
<Switch>
<Route exact path="/" component={FirstPage} />
<Route path=":id" component={Panorama} />
</Switch>
</BrowserRouter>
</div>
)
}
}
ReactDOM.render(<App/>,document.getElementById('container'));
The FirstPage.js is something like this
import React from 'react';
import ReactDom from 'react-dom' ;
import $ from 'jquery' ;
import {Panorama} from './Panorama.js';
import {Redirect,Link} from 'react-router-dom';
import {withRouter} from 'react-router';
class FirstPage extends React.Component{
constructor(props){
super(props);
this.state={
list:[],
images:[],
isClicked:false,
redirect:true,
imageUrl:''
}
this.loadImages=this.loadImages.bind(this);
this.loadOne=this.loadOne.bind(this);
}
componentDidMount(){
window.addEventListener('load',this.loadImages);
}
loadImages(){
console.log("load");
var that=this;
$.ajax({
type:'GET',
url:'https://demo0813639.mockable.io/getPanos',
datatype:'jsonp',
success:function(result){
var images=that.state.images;
for(var i=0;i<result.length;i++){
that.state.images.push({"pano":result[i].pano,"name":result[i].name});
}
that.setState({
images:images
})
}
})
}
loadOne(pano){
console.log("pano: ",pano);
this.setState({
isClicked:true,
imageUrl:pano
})
//this.props.history.push(`/image/${pano}`)
}
render(){
var list=this.state.list;
console.log("Image URL: "+this.state.imageUrl);
return this.state.isClicked?<Link to={`${this.state.imageUrl}`}/>:
<div> {this.state.images.map((result)=>{
return(<div className="box">
<div className="label">{result.name}</div>
<img src={result.pano} className="image col-md-3" onClick={this.loadOne.bind(this,result.pano)}/>
</div>
)
})}
</div>
}
}
module.exports={
FirstPage:FirstPage
}
This page makes an ajax call and loads four images on the screen.If clicked on one of those images, another js file is supposed to be called with the id of that image so that the particular image can be seen in full screen.
import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
import {Link} from 'react-router-dom';
class Panorama extends React.Component{
render(){
console.log("Image: "+ props.match.params.id);
return(
<div>
<img src={`${props.match.params.id}`}/>
</div>
)
}
}
module.exports={
Panorama:Panorama
}
Although I get no errors in the console, after clicking on an image nothing is coming up on the screen. What is wrong with the code?
The version of React router is v4.
Upvotes: 0
Views: 1361
Reputation: 3932
First thing you need to do as @Fawaz suggested, update your Route
<Route path="/panorama/:imageUrl" component={Panorama} />
As you are sending the url as parameter, you need to encode the url before loading image, and you can change the route using history API, no need to use the Link in your render method on some state change. I think the approach is wrong. I have updated the loadOne method as below:
loadOne(pano){
let imageUrl = encodeURIComponent(pano);
this.props.history.push(`/panorama/${imageUrl}`);
}
In Panorama Component, you can decode the url and load the image.
render() {
let url = decodeURIComponent(this.props.match.params.id);
return(
<div>
<img src={`${url}`}/>
</div>
)
}
FirstPage.js
import ReactDom from 'react-dom' ;
import $ from 'jquery' ;
import {Panorama} from './Panorama.js';
import {Redirect,Link} from 'react-router-dom';
import {withRouter} from 'react-router';
class FirstPage extends React.Component{
constructor(props){
super(props);
this.state={
images:[]
}
this.loadImages=this.loadImages.bind(this);
}
componentDidMount(){
window.addEventListener('load',this.loadImages);
}
loadImages(){
var that=this;
$.ajax({
type:'GET',
url:'https://demo0813639.mockable.io/getPanos',
datatype:'jsonp',
success:function(result){
that.setState({
images:result // I am assuming, result is array of objects.
})
}
})
}
loadOne(pano){
let imageUrl = encodeURIComponent(pano);
this.props.history.push(`/panorama/${imageUrl}`);
}
render(){
return <div>
{this.state.images.map((result)=>{
return(<div className="box">
<div className="label">{result.name}</div>
<img src={result.pano} className="image col-md-3"
onClick={this.loadOne.bind(this,result.pano)}/>
</div>)
})}
</div>
}
}
module.exports={
FirstPage:FirstPage
}
Upvotes: 1
Reputation: 3560
Your path needs to match the one you're calling. Change your second route to :
<Route path="/image/:id" component={Panorama} />
Upvotes: 0