简体   繁体   中英

Why the same prop is array in parent component and isn't array anymore if passed to child component

I have this component:

class SuppliersPage extends React.Component {
  render() {
    const suppliersList = this.props.suppliers.map(supplier => (
      <ListRow name={supplier.name} key={supplier.id} />
    ));

    return (
      <div className="row">
        <div className="col-sm-4">
          <div className="Section boxed rounded">
            <ButtonNew />
            {
              this.props.ui.list.loading ? 'loading' :
              <table className="table table-hover table-condensed">
                <tbody>
                  { suppliersList }
                </tbody>
              </table>
            }
          </div>
        </div>
        <div className="col-sm-8">
          <div className="Section boxed rounded">
            <Form />
          </div>
        </div>
      </div>
    );
  }
}

It works well: when this.props.ui.list.loading is true it shows "loading" while when this.props.ui.list.loading becomes false it shows the list of suppliers.

Now, I'd like to extract the suppliersList into its own components having in the end three components:

  1. SuppliersPage
  2. List
  3. ListRow

So I do this:

// Page.jsx

class SuppliersPage extends React.Component {
  render() {
    return (
      <div className="row">
        <div className="col-sm-4">
          <div className="Section boxed rounded">
            <ButtonNew />
            {this.props.ui.list.loading ? 'loading' : <List suppliers={this.props.suppliers} />}
          </div>
        </div>
        <div className="col-sm-8">
          <div className="Section boxed rounded">
            <Form />
          </div>
        </div>
      </div>
    );
  }
}

As you can see, I have removed all the logic that creates the list of suppliers and that renders the table with it.

I've moved all this logic in List.jsx that is this:

// List.jsx
export default (suppliers) => {
  const suppliersList = suppliers.map(supplier => (
    <ListRow name={supplier.name} key={supplier.id} />
  ));

  return (
    <table className="table table-hover table-condensed">
      <tbody>
        { suppliersList }
      </tbody>
    </table>
  );
};

Nothing complex: I simply process the array of this.props.suppliers directly in the List component.

But here comes the problem: running this code throws an error:

Uncaught TypeError: suppliers.map is not a function at ./assets/components/Business/Suppliers/List.jsx.exports.default (List.jsx:5)

So, practically, it seems to me that if I do this.props.suppliers.map(...) in the Page component all works well, while if I pass this.props.suppliers to the child component List and do the same the passed value is not array anymore.

Any ideas about what is going on and how to solve the problem?

I really don't understand why in Page no error is thrown while it is thrown in the child component: the value should ever be the same, but it seems that I'm missing something in my thoughts.

Can you help me to better understand what's happening?

the first argument to List.jsx is a props hash, which of course has no function property named map just like the error message is saying. assuming you're trying to use object shorthand in your function args, you need to add some curly braces:

// List.jsx
export default ({suppliers}) => {
// ...

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