I have a react component that based on the url should import some data and then display it in another child component. When the page first loads it loads the initial data as the component state in componentDidMount()
. As for further url changes, they are handled in componentDidUpdate()
export default class Info extends React.Component{
constructor(props){
super(props);
this.state={
element:null
}
}
componentDidMount(){
switch(this.props.match.params.id){
case 'legende': import('../data/legends.json').then((data)=>{
this.setState({
element:(<InfoDisplay data={data.content} />)
})
});break;
case 'istorie': import('../data/history.json').then((data) => {
this.setState({
element: (<InfoDisplay data={data.content} />)
})
}); break;
}
}
componentDidUpdate(prevProps){
if (this.props.match.params.id !== prevProps.match.params.id)
switch (this.props.match.params.id) {
case 'legende': import('../data/legends.json').then((data) => {
this.setState({
element: (<InfoDisplay data={data.content} />)
})
});
break;
case 'istorie': import('../data/history.json').then((data) => {
this.setState({
element: (<InfoDisplay data={data.content} />)
})
}); break;
default: break;
}
}
render(){
return (
<div style={{backgroundImage:`url(${background})`,height:'100vh',overflowX:'hidden',backgroundSize:'cover'}}>
<Navbar/>
{this.state.element}
</div>
)
}
}
My problem is that in spite of the state updating in the switch statement, the component won't re-render. I have no idea what's the problem with my approach. Can anyone help me out, please? Thanks!
Edit: Here is the code with shouldComponentUpdate()
instead of componentDidUpdate
:
import React from 'react'
import * as background from '../assets/img/background_main.png';
import Navbar from './Navbar'
import InfoDisplay from './InfoDisplay';
export default class Info extends React.Component {
constructor(props) {
super(props);
this.state = {
element: null
}
}
componentDidMount() {
switch (this.props.match.params.id) {
case 'legende': import('../data/legends.json').then((data) => {
this.setState({
element: (<InfoDisplay data={data.content} />)
})
}); break;
case 'istorie': import('../data/history.json').then((data) => {
this.setState({
element: (<InfoDisplay data={data.content} />)
})
}); break;
}
}
shouldComponentUpdate(nextProps,nextState) {
if (this.props.match.params.id !== nextProps.match.params.id && nextProps) {
switch (nextProps.match.params.id) {
case 'legende': import('../data/legends.json').then((data) => {
this.setState({
element: (<InfoDisplay data={data.content} />)
})
}); return true;
case 'istorie': import('../data/history.json').then((data) => {
this.setState({
element: (<InfoDisplay data={data.content} />)
})
});return true;
default: return false;
}
}
return true;
}
render() {
return (
<div style={{ backgroundImage: `url(${background})`, height: '100vh', overflowX: 'hidden', backgroundSize: 'cover' }}>
<Navbar />
{this.state.element}
</div>
)
}
}