Closed jayair closed 6 years ago
When running a Jest test against App.js, I get "Unexpected token" at the = after userHasAuthenticated in
userHasAuthenticated = authenticated => {
this.setState({ isAuthenticated: authenticated });
}
The syntax seems correct according to the React docs. Anyone have a clue? Thanks.
@KelpDuNord Yeah the syntax looks fine. I'm not sure why it's complaining.
<RouteNavItem key={1} href="/signup">
I noticed you added key={1} but the section does not explain why (or even if the reason why is because it will be used later). Curious what this is needed for?
@x11joe React needs keys when you are creating a list of components. You can read more about it here - https://reactjs.org/docs/lists-and-keys.html
I find this bit of code particularly baffling:
export default ({ component: C, props: cProps, ...rest }) => <Route {...rest} render={props => <C {...props} {...cProps} />} />;
The combo of ES6 with React idioms in the context of shorthand code makes it inscrutable.
@lucasgonze yeah I agree I had to spend like an hour wrapping my head around that the first time lol
@lucasgonze @TheDagger Yeah I can see that. Let me add more of an explanation to that section.
Just added a better explanation - https://github.com/AnomalyInnovations/serverless-stack-com/commit/6be7f67ae12dd4619c842c8b0a86a282ce628fd2
I had one more question on this section, the code <Route {...rest} render={props => <C {...props} {...cProps} />} />;
I get most of this now, but the part I don't get in particular is {...props} {...cProps} />}
. My understanding is this creates the properties and the values that go with the properties. This makes sense except for one thing. My understanding of attributes is it has to be formatted like this, <a href="hey" custom="something">test</a>
. The = in particular here is where I am confused because I noticed that is not in the example but somehow it still works? How is this working with the equal omitted? The translation in my head looks like this right now <C isAuthenticated true />
In the case of App passing that in as a property, does it not need equal in this case? Shouldn't it be <C isAuthenticated = true />
? (I come html HTML/CSS/PHP, so this might be a newbie javascript question)
@x11joe I agree this part is pretty confusing. And JSX has not been my favorite feature of React but it ends up being fairly convenient in practice.
In this specific case, your idea is right. The spread operator {...props}
does it for you. Here is more info on it - https://reactjs.org/docs/jsx-in-depth.html#spread-attributes. The entire chapter is worth a read if you want to get a better understanding of JSX.
JS noob here: originally read {component: C, props: cProps, ...rest}
as assigning values C
and cProps
to properties component
and props
, but C
and cProps
are being assigned as aliases for the properties component
and props
.
export default ({ component: C, props: cProps, ...rest })
Finally, we take component (set as C) and props (set as cProps)
Could you name this behaviour so I can look up documentation for it or link to documentation for this behaviour so I can better understand how/when to use it?
@teejK Yeah it's called Destructuring https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Writing unreadable code like this is ridiculous, we write code for people to read not computers. I've been coding for 12 years, writing react since its release, when I saw this I laughed, then came here to vent. I run in to a lot of devs who do this to look smart under the guise that it is efficient.
export default ({ component: C, props: cProps, ...rest }) => <Route {...rest} render={props => <C {...props} {...cProps} />} />;
The spread operator is still tricky, but super handy. here is the same code written more verbosely, and perhaps easier to read, which IMO should be apart of any good tutorial
<AppliedRoute path="/login" exact component={Login} props={childProps}/>
import React, {Component} from 'react';
import {Route} from 'react-router-dom';
export default class AppliedRoute extends Component {
render() {
const Comp = this.props.component;
const childProps = this.props.props;
const exact = this.props.exact;
const path = this.props.path;
return (
<Route path={path} exact={exact} render={(routerProps) => {
return (
<Comp {...routerProps} {...childProps}/>
//spread operator is adding all properties of routerProps & childProps to Comp
// i.e. <Comp match={match} location={location} whatever={whatever}>
//this is useful because we cannot predict what gets passed in to childProps, and we probably dont know what is in routerProps because it is a library
);
}}/>
);
}
};
@kevinlbatchelor While what you are saying is true; I get plenty of comments from other folks who look at a simplified version and tell us that we should use the "modern version" because it's more "efficient".
That said, I do think code like this (as it is in a lot of other languages) will become more common as it gets adopted. There are going to be some growing pains for the JS world. In fact, this line is taken from the React Router docs which I assume some of our readers will try and go over.
This is why I decided to leave it this way but added a long explanation on how some of destructuring parts work - https://github.com/AnomalyInnovations/serverless-stack-com/commit/6be7f67ae12dd4619c842c8b0a86a282ce628fd2
Thanks for your comment. It'll help anybody else that is looking for a simpler way to write this. And I understand your frustration.
Does anyone know how to fix this error? TypeError: _this.props.userHasAuthenticated is not a function. (In '_this.props.userHasAuthenticated(true)', '_this.props.userHasAuthenticated' is undefined)
@twalkerjr22 Where exactly are you seeing this?
I have the same error as @twalkerjr22 . The error appear in a popup when I try to log in. I have read again the complete part two times but I don't find what I'm doing wrong...
@caronicolas Can you tell me exactly after which step in the tutorial do you start seeing this error?
@jayair, I have the same error as @carnicolas, the error is comes from within the try statement in the handleSubmit function in Login.js
It's just after this step :
Replace the alert('Logged in'); line with the following in src/containers/Login.js. this.props.userHasAuthenticated(true);
@caronicolas found it, I was missing a step: in App.js replace <Routes />
with <Routes childProps={childProps} />
Ok, thank you @alex-romanov, I insert a space between childProps and '=' sign... My bad... Sorry @jayair
@alex-romanov @caronicolas Glad you figure it out.
I am having the same issue with "this.props.userHasAuthenticated" is not a function. Unfortunately my problem wasn't the "Routes childProps={childProps} "
@d3lusional What's the issue you are having?
This issue was moved to https://discourse.serverless-stack.com/t/add-the-session-to-the-state/136
Link to chapter - https://serverless-stack.com/chapters/add-the-session-to-the-state.html