Reputation: 443
I have all the components listed in App.js
. I'm kinda lost as on how to pass values from one component to the other.
Here's how it should work:
When an item is selected in the first component (ItemList
), details are loaded in the second component (ItemDetails
). Then in the second component if I click "add", it's added to the third component (ItemSelection
).
How do I pass the clicked item in ItemList
to ItemDetails
, then pass it to ItemSelection
on button click?
App
component:
// dummy selectedItems array
let selectedItems = [
{
'name': 'item 3',
'type': ['car'],
'details': [ 'Detail 1', 'Detail 2', 'Detail 3' ]
},
{
'name': 'item 6',
'type': ['bike'],
'details': [ 'Detail 5', 'Detail 1']
}
]
<Container>
<ItemList/>
<ItemDetails/>
<ItemSelection selected={selectedItems}/>
</Container>
ItemList
component:
const LIST_ITEMS = require('./LIST_ITEMS.json');
const myList =
LIST_ITEMS.data.Items.map((Item) => (
<li key={Item.id} onClick={() => loadItem(Item.name)}>
{Item.name.toUpperCase()}
</li>
))
;
function loadItem(name){
console.log(name);
}
class ItemList extends Component {
render() {
return (
<div id="item-list-wrapper">
<h3>Select an Item</h3>
<ul id="item-list">{myList}</ul>
</div>
);
}
}
ItemDetails
component:
import React, { Component } from 'react';
class ItemDetails extends Component {
render() {
<div id="item-details">
// Additional details about the item
<button>Add to selection</button>
</div>
}
}
ItemSelection
component:
import React, { Component } from 'react';
class ItemSelection extends Component {
render() {
<div id="item-selection">
// List selected items
<h3>Selected Items</h3>
<div className="item-slot">
{this.props.selected[0] ? (
<div className="selected-details">
<h4>{this.props.selected[0].name}</h4>
<ul>
<li>{this.props.selected[0].details[0]}</li>
<li>{this.props.selected[0].details[1]}</li>
<li>{this.props.selected[0].details[2]}</li>
</ul>
</div>
) : (
<p>empty</p>
)}
</div>
</div>
}
}
Upvotes: 0
Views: 119
Reputation: 5182
First, I would recommend the article, "Lifting State Up", as referenced by @codekaizer in the comments.
The main principle that you want to take from the article is this
There should be a single "source of truth" for any data that changes in a React application.
For your situation, that single "source of truth" should be your App
component - the one that talks to ItemList
, ItemDetails
, and ItemSelection
.
The flow of communication between components should look like this:
ItemList
App
will tell me in a prop.App
will tell me in a prop.ItemDetails
App
will tell me in a propApp
will tell me in a prop.ItemSelection
App
will tell me in a prop.App
ItemList
to display? I'll pass on what I get from LIST_ITEMS.json
ItemDetails
to display the details for? I'll maintain this in my state
as currentItem
. Initially, no item's details will be displayed.
ItemList
is clicked, then I need to change my state's currentItem
to be the item clicked. (HINT: App
needs a function, and this function's callback needs to be passed to ItemList
)ItemSelection
to display? I'll maintain this in my state
as selectedItems
. Initially, there will be no items selected.
ItemDetails
is "selected", then I need to add that currently displayed item to my array of selectedItems
. (HINT: App
needs a function, and this function's callback needs to be passed to ItemDetails
)App
should maintain a state
with the currentItem
to be displayed in item details and the selectedItems
which will show up in the item selection list.App
needs a few functions that manipulate the currentItem
and the selectedItems
states.App
needs to pass those function callbacks to the children.I've coded up a basic example of how this all looks in action. By studying it and applying it to your situation, this should give you a better understanding of how to get components to "talk to each other."
Upvotes: 2