Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialA R
12,834 PointsFull Stack Javascript Project #10 - State Management question
Hi, I'm wondering a little about how to manage the state in the final project. I'm currently setting up a view that shows a single course and gives an option to update it. A lot of the completed projects I've seen include the API call on the page that uses the info, for example, on github user jordiguirao92 has the following solution:
class UpdateCourse extends Component {
state = {
title:'',
description:'',
estimatedTime:'',
materialsNeeded:'',
errors:[]
};
async componentDidMount() {
this.getCourse();
}
//Function in order to get the indicated course in the route. After that we set the information of the course to the component state.
async getCourse() {
try{
let result = await axios.get(`http://localhost:5000/api/courses/${this.props.match.params.id}`);
console.log(result.data);
this.setState({
title: result.data.title,
description: result.data.description,
estimatedTime: result.data.estimatedTime,
materialsNeeded:result.data.materialsNeeded,
});
} catch (error) {
console.log('Error fetching and parsing data', error);
if(error){
this.props.history.push('/notfound');
}
}
}
I feel like it makes more sense to store that API call along with the other requests context or in Data.js. Is there a best practice on this?
I see user patrickgermann has another solution on his github: (https://github.com/patrickgermann/FULL-STACK-APP/blob/master/client/src/Context.js)
componentDidMount(){
const { context } = this.props;
context.data.getCourse(this.state.id)
.then(course => {this.setState({
teacher: course.owner.firstName + ' ' + course.owner.lastName,
userId: course.userId,
title: course.title,
description: course.description,
estimatedTime: course.estimatedTime,
materialsNeeded: course.materialsNeeded,
})
})
.catch(err => {
this.props.history.push('/error'); // push to history stack and route to error page
});
}
I've tried implementing something similar on my project (https://github.com/AeronRoemer/full-stack-react/tree/master/client). I'm not sure where it's best to store the call to the API, Data or Context. I've tried calling my 'get single course' function from this.props.context.data, but for some reason when I access it via context it works. I'm not sure what's the best method here; anyone have input?
export default class SingleCourse extends Component {
state = {
course: {},
}
componentDidMount(){
const idMatch = this.props.match.params.id
this.props.context.actions.getCourse(idMatch).then(course =>{
this.setState(() => {
return { course: course }
})}).catch(err => console.log(err))
}
2 Answers
A R
12,834 PointsIn this project, the Data file seems to serve the same function, more or less. Do you have any idea why when I call my 'get single course' function from this.props.context.data it fails, but for some reason when I access it via context/actions (as in the current code) it works?
Blake Larson
13,014 Pointskinda hard to tell outside looking in exactly what you are asking but it could be you are calling getCourse
which is in the context actions objects in the value
object passed in, but it's not in the data instance created in the Provider component. It's getCourseData
in the new Data() instance.
A R
12,834 PointsI think I had an error previously with the .this binding on the course data functions. Thanks for your input!
Blake Larson
13,014 PointsBlake Larson
13,014 PointsA common practice with React and state management libraries like Redux is to have a separate /actions folder where axios(or any request library) requests are handled. Here is a file tree of a project's separation of the two. -----> https://github.com/bradtraversy/devconnector_2.0/tree/master/client/src
You can then just import the functions and call them when needed.