Reputation: 534
This is the code, so I have a component which renders a columns of intervals and I want to change the color of the table on click and drag but what happens is instead it changes everything... I'm a complete beginner, So I have really no idea how will I do that..
import React, { Component } from 'react';
class TableBody extends Component {
constructor(props) {
super(props);
this.state = {
intervalItems: this.props.intervalItems,
flag: 0,
bgColor: '',
};
}
_mouseDown() {
this.setState(prevState => ({
flag: 1,
}));
}
_mouseUp() {
this.setState(prevState => ({
flag: 0,
}));
}
_mouseDrag(iD) {
if (this.state.flag == 1) {
this.setState(prevState => ({
bgColor: 'green',
}));
} else {
this.setState(prevState => ({
bgColor: '',
}));
}
}
render() {
const { dayItems, intervalItems } = this.props;
return (
<tbody>
{dayItems.map(v => (
<tr key={v.id}>
<th>
<div>{v.day}</div>
</th>
{this.state.intervalItems.map((v, i) => (
<td
key={v.id}
onMouseDown={() => this._mouseDown()}
onMouseMove={() => this._mouseDrag()}
onMouseUp={() => this._mouseUp()}
className={`table-inside-default ${this.state.bgColor}`}
>
{v.interval}
</td>
))}
</tr>
))}
</tbody>
);
}
}
export default TableBody;
Upvotes: 3
Views: 794
Reputation: 1408
When you call _mouseUp()
, _mouseDrag()
or_ mouseDown()
functions you change the color on the TableBody element and every single <td>
item is getting the color from that property, so the color isn't individual to each <td>
.
What I suggest you to do is create a child component with the <td>
so the color and other properties you put in the child component will be individual to each child element. It would be something like this:
class TableBody extends Components {
...
render() {
return (
<tbody>
...
{this.state.intervalItems.map((v, i) => (
<ItemTable item={v} />
))}
</tbody>
)
}
}
class ItemTable extends Component {
constructor(props) {
super(props);
this.state = {
flag: 0,
bgColor: '',
};
}
_mouseDown() {
this.setState(prevState => ({
flag: 1,
}));
}
_mouseUp() {
this.setState(prevState => ({
flag: 0,
}));
}
_mouseDrag(iD) {
if (this.state.flag == 1) {
this.setState(prevState => ({
bgColor: 'green',
}));
} else {
this.setState(prevState => ({
bgColor: '',
}));
}
}
render() {
const { item } = this.props;
return (
<td
key={item.id}
onMouseDown={() => this._mouseDown()}
onMouseMove={() => this._mouseDrag()}
onMouseUp={() => this._mouseUp()}
className={`table-inside-default ${this.state.bgColor}`}
>
{v.interval}
</td>
)
}
}
Upvotes: 0
Reputation: 857
It looks like what's happening is that you're updating the color for all of your <td>
tags at once. This is happening because they are all referencing the same piece of state, this.state.bgColor
. When one td
is changed, the component is re-rendered and all the elements pointing to this.state.bgColor
will show up as the same color.
You might consider adding another property to your state, such as this.state.activeItem
, and update it from your _mouseDrag
function. Based on your activeItem
, you can then set a designated color so that only that one is being updated. You might want to reset the activeItem
in a separate function so that it gets cleared in between mouse events.
Upvotes: 4