简体   繁体   中英

React.js : Passing Props from a Function to a Component

I'm trying to have App (component) call Main (function) which in turn calls Leads (component) and I want the props to follow. Main is the function that returns all the routes for my App. I'm using React Router v4.

I've simplified the code as much as possible below, hopefully not too much:

App calls Main and passes props: leads & library.

App.js

class App extends Component {
  render() {

    return (
      <div>
        <nav>
          <Link to="/library">Library</Link>
          <Link to="/leads">Leads</Link>
        </nav>
        <Main 
          leads={this.state.leads}
          library={this.state.library}
        />
      </div>
    );
  }
}

export default App;

Props are available here, no problem. My understanding however is that props is a local variable to the function Main, so having something point to it is the issue as props is destroyed once the function has run.

Main.js (simplified)

    const Main = (props) => (

    <main>
        <Switch>
            <Route exact path="/leads" render={(props) => (
                <Lead
                    {...props}
                    leads={props.leads}
                /> )}
            />
        </Switch>
    </main>
)

export default Main;

Here, this.props.leads in Leads.js points to null and {Object.keys(this.props.leads)} fails. (I've removed the code for renderLeads() for simplicity)

Leads.js (simplified)

class Lead extends React.Component {

    render() {

        return (
            <div>
                <h2>Leads</h2>
                <table>
                    <tbody>
                        {Object.keys(
                            this.props.leads).map(
                            this.renderLeads)}
                    </tbody>
                </table>
            </div>
        );
    }
}


export default Lead;

I've "solved" this problem by making Main an extended class of React.Component. I still feel Main should be a function has it only manipulates the data and doesn't hold data of its own...

  1. Should Main be a function?
  2. Is my assessment of the situation accurate?
  3. What would the proper way of passing props from Main to Leads be?

Thanks in advance.

Your mistake is known by "variable shadowing", when you declare a variable in a inner scope with the same name of another one that lives in a upper scope, in this case, the variable 'props'.

In the Main.js, you're rendering the <Lead /> passing an functional component to the route, passing the props that the Router gives to you, not the one you pass when you rendering <Main /> in the App.js.

I know is a bit confusing, but this explains why it worked when you change Main to an Class component, you probably was calling with this.props , right? So in this case you calling the right one.

You can decide if <Main /> should be a functional component or an class, but usually components that don't have state should be functional. You can simply change the names of your props in your outer scope (in the main) or in the inner (Route). Example:

<Route exact path="/leads" render={(routerProps) => (
        <Lead
            {...routerProps}
           leads={props.leads}
        /> )}
    />

Now, we're passing the right props in the leads.

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