React: Passing State Into Child Components As A Prop
Passing State to Child Component
We have previously shown that we can update the state of a component. We can also pass a state into a child component as a prop, and then change the display of that child component based on this state. For example in our little location based application that we are building here:
class App extends React.Component {
// initialize state
state = { lat: null, long: null, errorMessage: "" };
componentDidMount() {
window.navigator.geolocation.getCurrentPosition(
(position) =>
this.setState({
lat: position.coords.latitude,
long: position.coords.longitude,
}),
(err) => {
this.setState({ errorMessage: err.message });
}
);
}
// react requires us to define render
render() {
// if there is an error message and no position data
if (this.state.errorMessage && !this.state.lat) {
return (
<LatLongCard>
<div className="description">Error: {this.state.errorMessage}</div>
</LatLongCard>
);
// if there is no error message and there IS position data
} else if (!this.state.errorMessage && this.state.lat) {
return (
<LatLongCard>
<div className="description">Latitude: {this.state.lat}</div>
<div className="description">Longitude: {this.state.long}</div>
<SeasonDisplay lat={this.state.lat} />
</LatLongCard>
);
// if no error message and no position data
} else {
return (
<LatLongCard>
<div className="description">Loading Location...</div>
</LatLongCard>
);
}
}
}
We have our SeasonDisplay
child component inside of the LatLongCard
component. We were using the state to simply display the latitude and longitude when we retrieved them, but now we can see that we have also passed the state of lat
as a prop into SeasonDisplay
. We can then go to this component and modify what it shows based on this input.
// depending on the month and latitude determine if it is summer or winter
const getSeason = (lat, month) => {
if (month > 2 && month < 9) {
return lat > 0 ? "summer" : "winter";
} else {
return lat < 0 ? "summer" : "winter";
}
};
const SeasonDisplay = (props) => {
const season = getSeason(props.lat, new Date().getMonth());
return <div> {season} </div>;
};
So we have made a function to decide whether it is summer or winter depending on the month and the latitude that we passed in as a prop. By the way if the getSeason
function is confusing please see the docs on the Ternary Operator.
Then we can easily modify this use an image or an icon instead of the string like so.
const SeasonDisplay = (props) => {
const season = getSeason(props.lat, new Date().getMonth());
const seasonIcon = season === 'winter' ? '❄️':'🌞';
return <div> Season:{seasonIcon} </div>;
};
Extracting Options to Config Objects
There is a way to refactor this component to make it fit with convention and be easier for others to maintain in the future. We can extract the options into an object called seasonConfig
and place all the options in that object at the top of the component. Then we can reference and deconstruct that object in the display function.
const seasonConfig = {
summer: {
text: "It is summer.",
emoji: "🌞",
},
winter: {
text: "It is Winter.",
emoji: "❄️",
},
};
// depending on the month and latitude determine if it is summer or winter
const getSeason = (lat, month) => {
if (month > 2 && month < 9) {
return lat > 0 ? "summer" : "winter";
} else {
return lat < 0 ? "summer" : "winter";
}
};
const SeasonDisplay = (props) => {
const season = getSeason(props.lat, new Date().getMonth());
// deconstruct seasonConfig object
const{text, emoji} = seasonConfig[season];
return (
<div>
<div> Icon: {emoji} </div>
<div> Text: {text} </div>
</div>
);
};
Comments
Recent Work
Basalt
basalt.softwareFree desktop AI Chat client, designed for developers and businesses. Unlocks advanced model settings only available in the API. Includes quality of life features like custom syntax highlighting.
BidBear
bidbear.ioBidbear is a report automation tool. It downloads Amazon Seller and Advertising reports, daily, to a private database. It then merges and formats the data into beautiful, on demand, exportable performance reports.