Reputation: 108
I've just started learning React. I'm working on a project for practice. It has two different components Nav & Main.I'm calling these components in App.js. My Nav component has a number of coloured divs which show up on clicking the plus icon. Now, I want to create a new div in Main.js on click of a coloured div in Nav.js. This new div should have the same background colour as the one we click on. I'm confused how to do it. Please! Help me out. This is my Nav component.
const Nav = () => {
const [showColors, setShowColors] = useState(false);
return(
<div className="NavBar">
<h1 className="NavHeading">Notes.</h1>
<div onClick={() => setShowColors(!showColors)} className="PlusImg"></div>
<div className={showColors ? "" : "ColorBar"}>
<div className="Color Color1"></div>
<div className="Color Color2"></div>
<div className="Color Color3"></div>
<div className="Color Color4"></div>
<div className="Color Color5"></div>
</div>
</div>
);
};
export default Nav;
This is my Main component.
const Main = () => {
return(
<div className="Main">
<div className="NoteItem"></div>
</div>
);
};
export default Main;
I want to create new div with class name of NoteItem as the one written in the Main component.
Upvotes: 0
Views: 2617
Reputation: 27245
I'm not 100% sure I understand what you're trying to do. Apologies if I've misunderstood.
I'd approach this by keeping track of the items that have been added in component state:
const App = () => {
// starting with an empty array
const [items, setItems] = React.useState([]);
And defining a handler for adding an item:
const App = () => {
const [items, setItems] = React.useState([]);
// itemClass is just a string, e.g. "color1" or "color5"
const addItem = itemClass => setItems([...items, itemClass]);
The spread syntax used above creates a new array containing the previous array plus the new item:
const oldArr = ['color1','color2'];
const newArr = [...oldArr, 'color3']
// newArr is now ['color1', 'color2', 'color3'];
You can then pass the items
to Main as a prop, which can render a div for each item:
const App = () => {
const [items, setItems] = React.useState([]);
const addItem = itemClass => setItems([...items, itemClass]);
return (
<Main items={items} /> {/* pass items array to Main */}
);
}
const Main = ({items}) => { // {items} is the equivalent of props.items
// render a div for each item in the items array
return items.map( item => (
<div className={item}>This item has a class of {item}</div>
)
}
And pass the addItem
handler to Nav
so it can tell App to add the clicked item:
const Nav = ({addItem}) => {
return (
<div className={showColors ? "" : "ColorBar"}>
<div onClick={() => addItem('Color1')} className="Color Color1"></div>
{/* repeat for Color2, etc. */}
</div>
);
}
With this place, when a Nav div is clicked an item will get added to App's items array, which will trigger a re-render, passing the updated array to Main, and you'll see the new div.
In the Main
component above you're going to get a react key warning. I omitted the key in the interest of readability, but you'll need to include a key prop that's unique for each item. The easiest way to do this is to just use the index of the iteration:
const Main = ({items}) => {
// add key={index} to make react happy
return items.map((item, index) => (
<div key={index} className={item}>This item has a class of {item}</div>
)
}
Also, the items.map
call will blow up if items isn't provided. You can dodge this by setting it to an empty array by default:
const Main = ({items = []}) => {
// ...
}
Upvotes: 1
Reputation: 179
First of all you need to define your state in your App
component and pass it to your components as an argument because both your Nav
and Main
components needs to access your state. You can do it like this
class App extends React.Component{
constructor(){
super()
this.state = {
showColors: false
}
}
}
After that you can take elements color with the onClick
event listener. Define it in your state as well. And create a div element inside your Main component with it.
Dont forget to pass it as an argument to your Main
component too.
Upvotes: 0