Certainly.
If you want to pass instances of the component, what you're doing is fine except that you need to close those JSX tags:
{
src: <SVGComponent1 />,
...
Or if you want to pass the component class/function itself:
{
src: SVGComponent1,
...
It's not totally clear what you're trying to do in your usage, though -- what are you hoping to achieve by passing a component to the src attribute of an img tag?
Perhaps that's old code you forgot to update for passed components and you mean this:
const slides = items.map((item, index) => {
return (
<CarouselItem
onExiting={this.onExiting}
onExited={this.onExited}
key={index}
>
{item.src}
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
);
});
This ought to work just fine when a component instance was passed.
Note I also changed the key attribute, since I'm not sure passing a component to that will work!
I have an array of React Components that looks like this:
const [allSongs, setAllSongs] = useState([<Song/>,<Song/>])
but when I store it to localStorage with JSON.stringify and try to retrieve the list with JSON.parse, the array children have changed slightly, meaning I can't map over the elements to display them anymore:
localStorage.setItem('allSongs', JSON.stringify(allSongs))
const deSerializedArr = JSON.parse(localStorage.getItem('allSongs'))
console.log(allSongs)
//output is list of these --> {$$typeof: Symbol(react.element), type: function, key: null, ref: null, props: {}, …}
console.log(deSerializedArr)
// output is list of these --> {key: null, ref: null, props: {}, _owner: null, _store: {}}Side note: It might be a bad practice to have an array of react components which I will later map over to display, but undoing this would require me to rewrite a lot other code
How to store components in an array and render them when I need in React?
How to Load a react components in an array and display them
In ReactJS, can I declare an array of components? and return certain component - Stack Overflow
Rendering React Components from Array of Objects
Have you consider using the new React Fragments? (in v16)
This would be the simplest solution as it would by pass the whole array/key issue.
If you need to pass key, then I'd suggest to simply require the components to have the keys. This is how React works, so I wouldn't suggest you to hide this behavior behind an interface that might not be predictable.
If you really need to do this, then you can use React.cloneElement to clone the element and inject new properties:
React.cloneElement(element, { key: 'foo' });
If you’re always going to want to render all the components in your components file then you’re probably better off wrapping them in a React.Fragments tag.
Best practise is just to export this as a simple function that returns the components rather than as a constant.
So...
const Components = props => {
return (
<React.Fragment>
<ComponentOne/>
<ComponentTwo/>
</React.Fragment>
)
}
export default Components
That allows you to put multiple components next to each other without a DOM element containing them.
You should then just be able to render that by using it as a normal component and it’ll render all of them, so just import it then...
<Components />
Otherwise, if you want to treat them like an array, you have a function for free on the React object you’ve imported...
React.Children.toArray(arrayOfComponents)
You pass it an array of components (like in your original question) and it allows you to sort and slice it if you need to then you should be able to just drop it in the return of your render function
You can map the list of stations to ReactElements.
With React >= 16, it is possible to return multiple elements from the same component without needing an extra html element wrapper. Since 16.2, there is a new syntax <> to create fragments. If this does not work or is not supported by your IDE, you can use <React.Fragment> instead. Between 16.0 and 16.2, you can use a very simple polyfill for fragments.
Try the following
// Modern syntax >= React 16.2.0
const Test = ({stations}) => (
<>
{stations.map(station => (
<div key={station.call} className='station'>{station.call}</div>
))}
</>
);
// Modern syntax < React 16.2.0
// You need to wrap in an extra element like div here
const Test = ({stations}) => (
<div>
{stations.map(station => (
<div className="station" key={station.call}>{station.call}</div>
))}
</div>
);
// old syntax
var Test = React.createClass({
render: function() {
var stationComponents = this.props.stations.map(function(station) {
return <div className="station" key={station.call}>{station.call}</div>;
});
return <div>{stationComponents}</div>;
}
});
var stations = [
{call:'station one',frequency:'000'},
{call:'station two',frequency:'001'}
];
ReactDOM.render(
<div>
<Test stations={stations} />
</div>,
document.getElementById('container')
);
Don't forget the key attribute!
https://jsfiddle.net/69z2wepo/14377/
I have an answer that might be a bit less confusing for newbies like myself. You can just use map within the components render method.
render () {
return (
<div>
{stations.map(station => <div key={station}> {station} </div>)}
</div>
);
}