javascriptreactjspure-function

Passing array into React stateless component


Following example from book Learn ReactJS, my attempt to pass an array in the same manner only yields errors.

From the Github examples by authors: https://github.com/MoonHighway/learning-react/blob/master/chapter-04/03-react-components/04-components.html

 const IngredientsList = ({items}) =>
        React.createElement("ul", {className: "ingredients"},
            items.map((ingredient, i) =>
                React.createElement("li", { key: i }, ingredient)
            )
        )
    const items = [
        "1 lb Salmon",
        "1 cup Pine Nuts",
        "2 cups Butter Lettuce",
        "1 Yellow Squash",
        "1/2 cup Olive Oil",
        "3 cloves of Garlic"
    ]
    ReactDOM.render(
      React.createElement(IngredientsList, {items}, null),
      document.getElementById('react-container')
    )

I stood up a React app with create-react-app, and wrote the following in App.js:

const things = [
    'foo',
    'bar',
    'baz',
    'fizz',
    'buzz'
];

const App = ({things}) =>
    React.createElement("ul",{className: "thingsAndStuff"},
    things.map((item, value) =>
        React.createElement("li", {key:value}, item)
        )
    );

In index.js I had ReactDom.render as:

ReactDOM.render(React.createElement(App, null, null), document.getElementById('root'));

I received an error "things.map not a function". When I removed the destructured things (const App = () => ...), my component worked.

My questions are: 1. How is things being pulled into App() when both were declared with const and conceivably not in the same scope, and things is not specifically being passed into the function? 2. Would the example code have worked for me had I done something different?

Thanks!


Solution

  • The props are passed into a component when using createElement:

      React.createElement(App, /*props:*/ { things });
    

    The first snippet does that. The second does not, and therefore the local variable things will be undefined, and therefore you can't iterate over it. If you want to access a global variable, you just have to make sure that no local variable has the same name, so this would also work:

    const App = () => React.createElement("ul",
         { className: "thingsAndStuff" },
         things.map((item, value) =>
            React.createElement("li", {key:value}, item)
         )
    );