简体   繁体   中英

React passing a prop to components return undefined

I'm really confused as to why when I route to http://localhost:3000/subjects/physics of my project.

The variable gradeSelection is defined in App.js state. It is passed to subjectCards.js component via props as gradeSelection, which passes it onto a Subject.js component via props as gradeSelection.

However, this.props.gradeSelection in Subjects.js returns undefined.

Is there something I might possibly be doing wrong?

Console output:

App.js: Year 12             // correct
subjectCards.js: Year 12    // correct
Subject.js: undefined       // not correct

App.js

constructor(props) {
  super(props);
  this.state = {
    gradeSelection: "Year 12"
  };
}

render() {
  console.log("App: "+this.state.gradeSelection)
  return (
    <Route path="/subjects" render={(props)=>(<SubjectCards {...props}  gradeSelection={this.state.gradeSelection} />)} />
);


}

subjectCards.js

let display;

console.log("subjectCards.js: "+props.gradeSelection)
display = <Route path="/subjects/:subjectName" render={(props)=><Subject {...props} gradeSelection={props.gradeSelection}/>} />


return (
  display
);

Subject.js

constructor(props) {
  super(props);
  console.log("Subject.js: "+this.props.gradeSelection);  // undefined
}

Thank you!

EDIT:

When console.log(props) or console.log(this.props) in Subjects.js constructor. gradeSelection inside the console output is still undefined..

I've tried passing a string to gradeSelection in subjectCards.js and the console output was correct in returning the string in Subject.js..

display = <Route path="/subjects/:subjectName" render={(props)=><Subject {...props} gradeSelection={"props.gradeSelection"}/>} />

Without seeing the rest of your code, I'm going to assume that subjectCards.js is a functional component that looks like this. If it's not, could you please post the complete component?

function SubjectCards(props) {
  let display

  console.log('subjectCards.js: ' + props.gradeSelection)

  display = (
    <Route
      path="/subjects/:subjectName"
      render={props => (
        <Subject {...props} gradeSelection={props.gradeSelection} />
      )}
    />
  )

  return display
}

What I'm seeing wrong with this code in your particular use case is that on line 1, you have an argument with the name of props . If you follow the code down to line 9, you'll notice that the anonymous function call inside render also has a props argument. On line 10, you're calling props.gradeSelection which would look inside the argument found on line 9 and not the argument found on line 1, giving you undefined.

There are a couple different ways of fixing this. One way I'd recommend is destructuring your argument props on line 1.

function SubjectCards({ gradeSelection }) { // See how we went from props to {gradeSelection}
  let display

  console.log('subjectCards.js: ' + gradeSelection)

  display = (
    <Route
      path="/subjects/:subjectName"
      render={props => <Subject {...props} gradeSelection={gradeSelection} />}
    />
  )

  return display
}

You can see an example of this over at https://mo9jook5y.codesandbox.io/subjects/math

You can play around with the example here: https://codesandbox.io/s/mo9jook5y

As Randy Casburn said in the comments, your reference should be to props.gradeSelection and not this.props.gradeSelection .

Props is received as an input to your constructor function (ie constructor(props) ), and therefore should be referenced as such. If you need to manipulate it before rendering or manage it locally you can pass that to the state for Subject within the constructor.

You may use like:

//subjectCards.js
render={({gradeSelection, ...other}) => <Subject {...other} 
      gradeSelection={gradeSelection}/>}

//Subject.js
console.log(props.gradeSelection)

But wait, you can just simply pass the props, it has all you need (including gradeSelection):

//subjectCards.js
render={(props) => <Subject {...props} />}

//Subject.js
console.log(props.gradeSelection)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM