Reputation: 205
React newb here. Attempting to set className on (dynamically created but static in example) child element(s). Click on child and parent receives event and changes child's styles accordingly. Trivial in vanilla.js but want to know the "react way".
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = { sel : "none"};
this.handleChildClick = this.handleChildClick.bind(this);
}
render() {
return (
<div className="App">
<header className="App-header">
{this.state.sel}
<div>
<ChildClass onClick={this.handleChildClick}/>
</div>
</header>
</div>
);
}
handleChildClick = (event) => {
// console.log(event);
// want to change background color of child by adding className
this.setState({
sel : event.target.innerHTML
})
}
}
class ChildClass extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div onClick={this.props.onClick}>
div or li or button
</div>
)
}
}
export default App;
-------- EDIT ----
<html>
<head>
<style>
div {
border: 1px solid black;
display: inline-block;
margin-right: 10px;
padding: 2px 4px;
}
.selected {
background-color: #09f;
}
</style>
</head>
<body>
<div id="d_1" class='clk'>one</div>
<div id="d_2" class='clk'>two</div>
<div id="d_3" class='clk'>three</div>
<script>
let ele = document.querySelectorAll('.clk');
ele.forEach(function(e,v,t) {
e.onclick = setThis;
});
var sel = '';
function setThis(e) {
if(sel.length > 0) {
document.getElementById(sel).classList.remove('selected');
}
document.getElementById(e.target.id).classList.add('selected');
sel = e.target.id;
}
</script>
</body>
</html>
Upvotes: 0
Views: 6055
Reputation: 17608
I don't know if this is what you want exactly, but here is a very simple example.
class App extends React.Component {
state = { childClass: "" };
handleChildClick = e =>
this.setState( {
childClass: e.target.innerHTML,
} );
render() {
return (
<div className="App">
<ChildClass
childClass={this.state.childClass}
onClick={this.handleChildClick}
/>
</div>
);
}
}
const ChildClass = props => (
<div onClick={props.onClick} className={props.childClass}>
<li>blue</li>
<li>red</li>
<li>yellow</li>
</div>
);
ReactDOM.render( <App />, document.getElementById( "root" ) );
.blue {
background-color: blue;
}
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Update after comments
Here is the example according to your pure JS code if I understand it right :) I'm using a hardcoded div
list here as you can see. This is because I don't know how will you generate your divs. Maybe you will get them from an array. If this is so this code will be much more practical. Map through the array and create the divs according to their id's and so on. But, here is the hardcoded version.
class App extends React.Component {
state = { selected: "" };
handleChildClick = e => this.setState( { selected: e.target.id } );
render() {
return (
<div className="App">
<ChildClass
selected={this.state.selected}
onClick={this.handleChildClick}
/>
</div>
);
}
}
const ChildClass = props => (
<div>
<div
id="d_1"
onClick={props.onClick}
className={props.selected === "d_1" ? "clk" : ""}
>
one
</div>
<div
id="d_2"
onClick={props.onClick}
className={props.selected === "d_2" ? "clk" : ""}
>
two
</div>
<div
id="d_3"
onClick={props.onClick}
className={props.selected === "d_3" ? "clk" : ""}
>
three
</div>
</div>
);
ReactDOM.render( <App />, document.getElementById( "root" ) );
.clk {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Here is the map version of how you can generate divs maybe.
const ChildClass = ( props ) => {
const divs = [
{ id: "d_1", text: "one" },
{ id: "d_2", text: "two" },
{ id: "d_3", text: "three" },
];
return (
<div>
{divs.map( el => (
<div
key={el.id}
onClick={props.onClick}
id={el.id}
className={props.selected === el.id ? "clk" : ""}
>
{el.text}
</div>
) )}
</div>
);
};
Upvotes: 2
Reputation: 589
<ChildClass
onClick={this.handleChildClick}
className={this.state.sel}
/>
And you have to add className={this.props.className}
to your div
in ChildClass
Upvotes: 0