React-Router: Component Isolation
GitHub Repos
Intro
We will continue here working on our Twitch Clone Project called "Glitch".
We are are currently working on creating the StreamEdit component, and have just completed a new route in our last post that directs us to this component, as well as passed in the data that was required as props. More on that in the last post React-Router: Variable Route Parameters.
There is a problem here that we need to watch out for, which is Component Isolation. Currently if we navigate to one of the routes to edit a stream manually, without clicking through from the Stream List, the application state will not have loaded any streams data yet, and therefore that state data will not be available to the StreamEdit component. This is because we have designed this component poorly so far. It relies on the user going to the stream list first, which is not always going to be the case.
This brings us to a very important React-Router concept. Every component must fetch it's own data.
Luckily for us, we have already done part of this work. We wrote out all of our actions ahead of time, and we have one action that is designed to fetch a specific stream given an id.
// fetch stream
export const fetchStream = (streamId) => async (dispatch) => {
const response = await streams.get(`/streams/${streamId}`);
dispatch({ type: FETCH_STREAM, payload: response.data });
};
and then we can go inside of our StreamEdit component and make use of this action to retrieve the data we need for the store and then retrieve it.
import React, { Component } from "react";
import { connect } from "react-redux";
import { fetchStream } from "../../actions";
class StreamEdit extends Component {
componentDidMount() {
this.props.fetchStream(this.props.match.params.id);
}
render() {
console.log(this.props);
return <div>StreamEdit</div>;
}
}
const mapStateToProps = (state, ownProps) => {
// the stream that matches the ID in the URL
return { stream: state.streams[ownProps.match.params.id] };
};
export default connect(mapStateToProps, { fetchStream })(StreamEdit);
and then we can quickly display that data.
import React, { Component } from "react";
import { connect } from "react-redux";
import { fetchStream } from "../../actions";
class StreamEdit extends Component {
componentDidMount() {
this.props.fetchStream(this.props.match.params.id);
}
render() {
// if we have not retrieved stream yet use loading animation
if (!this.props.stream) {
return <div>Loading...</div>;
}
return (
<>
<h1>{this.props.stream.title}</h1>
<p>{this.props.stream.description}</p>
</>
);
}
}
const mapStateToProps = (state, ownProps) => {
// the stream that matches the ID in the URL
return { stream: state.streams[ownProps.match.params.id] };
};
export default connect(mapStateToProps, { fetchStream })(StreamEdit);
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.