I have a React component pulling from a file with images, copy, and other data needed for the app. The issue I'm coming up against is simply syntactical: how can I reference this data based on the state of the component?
data.js
looks like this (simplified version):
import changingAgents from '../public/images/changing-agents.jpg';
import cta from '../public/images/cta.jpg';
import logo from '../public/images/logo.jpg';
export const images = {
changingAgents,
cta,
logo,
}
export const copy = {
services: {
header: 'What are you looking for?',
firstTimeInvestor: {
title: 'First-Time Investor Service',
intro: 'At vero eos et accusamus et iusto odio dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti atque.',
},
changingAgents: {
title: 'Changing Agents',
intro: 'At vero eos et accusamus et iusto odio dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti atque corrupti.',
},
}
And here are the relevant parts of the component, Services.js
:
import { copy, images } from '../../data';
export default class Services extends Component {
state = {
segmentTrigger: 'changingAgents',
}
changeSegmentTrigger(chosenSegmentTrigger) {
this.setState({segmentTrigger: chosenSegmentTrigger})
}
render() {
return (
<div className="services">
<h2>{copy.services.header}</h2>
<Section backgroundImage={this.state.segmentTrigger} className="services__segment-triggers" >
<div className="services__segment-triggers__select">
<Button color="yellow" onClick={() => this.changeSegmentTrigger('firstTimeInvestor')} label="First-Time Investor" />
<Button color="yellow" onClick={() => this.changeSegmentTrigger('changingAgents')} label="Changing Agents" />
</div>
<div className="services__segment-triggers__info">
{/* Insert header here! */}
</div>
</Section>
</div>
)
}
}
Basically what I need to do is add text that will change depending on this.state.segmentTrigger
in <div className="services__segment-triggers__info">
. I tried a few variations to no avail, such as:
<h2>{copy.services.
${this.state.segmentTrigger}.title}</h2>
<h2>{copy.services.${this.state.segmentTrigger}
.title}`<h2>{copy.services.this.state.segmentTrigger.title}</h2>
Is this possible? I get syntax errors for the first two, and the third one just doesn't work (which seems obviously logical to me, it was a bit of a Hail Mary even trying it, as of course there is no key named this
in the copy.services
object).
The answer you're looking for is
<h2>{copy.services[this.state.segmentTrigger].title}</h2>
The reasoning is that you're trying to access a key of copy.services
, but that you will not know what key you're trying to access until the user starts clicking buttons, and which one you access will be dynamically decided.
The way objects and keys work in JavaScript, is that the key is technically a string, so using this example:
let x = {
test1: 4,
test2: 5,
'test3': 6
};
x.test1 // is 4
x.test2 // is 5
x.test3 // is 6
x['test1'] // is 4
x['test2'] // is 5
x['test3'] // is 6
const y = 'test1';
x.y // undefined. we never set a key of y.
x[y] // this is interpreted as x['test1'] so the result is 4