如何在反应中从嵌套地图迭代中切换单个元素
How to toggle a single element from nested map iteration in react
我是新手。我正在从事一个为工人创建轮班表的项目。创建了一个带有单元格的网格。当您单击一个单元格时,它会将其值从天数更改为 "Holiday",如果您再次单击它,它将变回天数。问题是当我单击一个单元格时,整行单元格都会更改它们的值。如何仅更改一个单元格的值?
这是我的代码...
export default class DayNames extends Component {
constructor(props) {
super(props);
this.state = {
isToggleOn: true
};
}
handleClick = e => {
this.setState(prevState => ({
isToggleOn: { ...prevState.isToggleOn, [e]: !prevState.isToggleOn[e] }
}));
};
render() {
//Getting number of days of month
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
const numberDaysOfMonth = new Date(year, month, 0).getDate();
let foo1 = [];
for (let i = 1; i <= numberDaysOfMonth; i++) {
foo1.push(i);
}
let foo2 = ["Ops1", "Ops2", "Ops3", "Ops4", "Ops5", "Ops6"];
const ops = foo2.map((elem, index) => {
return (
<div className="ops_header" key={index}>
{elem}
{foo1.map((cell, i) => {
return (
<div
className="operator"
data-id={cell}
key={i}
onClick={() => this.handleClick(i)}
>
{this.state.isToggleOn[i] ? "Holiday" : cell}
</div>
);
})}
</div>
);
});
return (
<div>
<div className="table">{ops}</div>
</div>
);
}
}
这是 link 到沙箱 .../components/DayNames/DayNames.js
https://codesandbox.io/s/react-toggle-day-0rjop
试试这个代码沙盒click here
或查看下面更新的组件。
import React, { Component } from "react";
import "./DayNames.css";
export default class DayNames extends Component {
foo2 = ["Ops1", "Ops2", "Ops3", "Ops4", "Ops5", "Ops6"];
constructor(props) {
super(props);
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
this.state = {
bgColor: "lightslategrey",
// isToggleOn: true,
days: Array(this.foo2.length)
.fill(0)
.map(x => Array(new Date(year, month, 0).getDate()).fill(0))
};
}
handleClick = (index, i) => {
const { days } = this.state;
days[index][i] = !days[index][i];
this.setState({
days
});
};
render() {
//Getting number of days of month
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
const numberDaysOfMonth = new Date(year, month, 0).getDate();
let foo1 = [];
for (let i = 1; i <= numberDaysOfMonth; i++) {
foo1.push(i);
}
const ops = this.foo2.map((elem, index) => {
return (
<div className="ops_header" key={index}>
{elem}
{foo1.map((cell, i) => {
return (
<div
className="operator"
data-id={cell}
key={i}
onClick={() => this.handleClick(index, i)}
>
{this.state.days[index][i] ? "Holiday" : cell}
</div>
);
})}
</div>
);
});
return (
<div>
<div className="table">{ops}</div>
</div>
);
}
}
我已经更新了代码,错误是您没有保留每个单元格状态。我修好了。查看状态天。
有很多方法可以做到这一点,在我的解决方案中,我使用了 Set
这给了 O(1)
复杂性
在设置、添加和删除切换日期时,这正是您所需要的:
import React, { Component } from "react";
import "./DayNames.css";
export default class DayNames extends Component {
constructor(props) {
super(props);
this.state = {
bgColor: "lightslategrey",
toggledDays: new Set()
};
}
createDayId = (columnIndex, rowIndex) => `${columnIndex}-${rowIndex}`;
handleClick = (columnIndex, rowIndex) => {
this.setState(prevState => {
const prevToggledDays = prevState.toggledDays;
const dayId = this.createDayId(columnIndex, rowIndex);
if (this.isDayToggled(columnIndex, rowIndex)) {
prevToggledDays.delete(dayId);
} else {
prevToggledDays.add(dayId);
}
return { toggledDays: prevToggledDays };
});
};
isDayToggled = (columnIndex, rowIndex) => {
const dayId = this.createDayId(columnIndex, rowIndex);
return this.state.toggledDays.has(dayId);
};
render() {
//Getting number of days of month
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
const numberDaysOfMonth = new Date(year, month, 0).getDate();
let foo1 = [];
for (let i = 1; i <= numberDaysOfMonth; i++) {
foo1.push(i);
}
let foo2 = ["Ops1", "Ops2", "Ops3", "Ops4", "Ops5", "Ops6"];
const ops = foo2.map((elem, columnIndex) => {
return (
<div className="ops_header" key={columnIndex}>
{elem}
{foo1.map((cell, rowIndex) => {
return (
<div
className="operator"
data-id={cell}
key={rowIndex}
onClick={() => this.handleClick(columnIndex, rowIndex)}
>
{this.isDayToggled(columnIndex, rowIndex) ? "Holiday" : cell}
</div>
);
})}
</div>
);
});
return (
<div>
<div className="table">{ops}</div>
</div>
);
}
}
然而有时依赖索引是危险的,但它似乎适合你的情况
希望对您有所帮助<3
好像你在切换时正在获取单元格的所有索引,我添加了另一个参数,它基本上是你的 foo2
的索引,并将切换条件从一个索引更改为两个 [i= foo1, i=foo2];
// This line changed from e => (e,index)
handleClick = (e, index) => {
// memories both index and put into one variable
const target = [e, index];
console.log(target);
this.setState(prevState => ({
// update state
isToggleOn: { ...prevState.isToggleOn, [target]: !prevState.isToggleOn[target] }
}));
};
let foo2 = ["Ops1", "Ops2", "Ops3", "Ops4", "Ops5", "Ops6"];
const ops = foo2.map((elem, index) => {
return (
<div className="ops_header" key={index}>
{elem}
{foo1.map((cell, i) => {
return (
<div
className="operator"
data-id={cell}
key={i}
// pass both indexes to handleClick();
onClick={() => this.handleClick(i, index)}
>
// togle based on indexes;
{this.state.isToggleOn[[i, index]] ? "Holiday" : cell}
</div>
);
})}
</div>
);
});
我是新手。我正在从事一个为工人创建轮班表的项目。创建了一个带有单元格的网格。当您单击一个单元格时,它会将其值从天数更改为 "Holiday",如果您再次单击它,它将变回天数。问题是当我单击一个单元格时,整行单元格都会更改它们的值。如何仅更改一个单元格的值?
这是我的代码...
export default class DayNames extends Component {
constructor(props) {
super(props);
this.state = {
isToggleOn: true
};
}
handleClick = e => {
this.setState(prevState => ({
isToggleOn: { ...prevState.isToggleOn, [e]: !prevState.isToggleOn[e] }
}));
};
render() {
//Getting number of days of month
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
const numberDaysOfMonth = new Date(year, month, 0).getDate();
let foo1 = [];
for (let i = 1; i <= numberDaysOfMonth; i++) {
foo1.push(i);
}
let foo2 = ["Ops1", "Ops2", "Ops3", "Ops4", "Ops5", "Ops6"];
const ops = foo2.map((elem, index) => {
return (
<div className="ops_header" key={index}>
{elem}
{foo1.map((cell, i) => {
return (
<div
className="operator"
data-id={cell}
key={i}
onClick={() => this.handleClick(i)}
>
{this.state.isToggleOn[i] ? "Holiday" : cell}
</div>
);
})}
</div>
);
});
return (
<div>
<div className="table">{ops}</div>
</div>
);
}
}
这是 link 到沙箱 .../components/DayNames/DayNames.js https://codesandbox.io/s/react-toggle-day-0rjop
试试这个代码沙盒click here
或查看下面更新的组件。
import React, { Component } from "react";
import "./DayNames.css";
export default class DayNames extends Component {
foo2 = ["Ops1", "Ops2", "Ops3", "Ops4", "Ops5", "Ops6"];
constructor(props) {
super(props);
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
this.state = {
bgColor: "lightslategrey",
// isToggleOn: true,
days: Array(this.foo2.length)
.fill(0)
.map(x => Array(new Date(year, month, 0).getDate()).fill(0))
};
}
handleClick = (index, i) => {
const { days } = this.state;
days[index][i] = !days[index][i];
this.setState({
days
});
};
render() {
//Getting number of days of month
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
const numberDaysOfMonth = new Date(year, month, 0).getDate();
let foo1 = [];
for (let i = 1; i <= numberDaysOfMonth; i++) {
foo1.push(i);
}
const ops = this.foo2.map((elem, index) => {
return (
<div className="ops_header" key={index}>
{elem}
{foo1.map((cell, i) => {
return (
<div
className="operator"
data-id={cell}
key={i}
onClick={() => this.handleClick(index, i)}
>
{this.state.days[index][i] ? "Holiday" : cell}
</div>
);
})}
</div>
);
});
return (
<div>
<div className="table">{ops}</div>
</div>
);
}
}
我已经更新了代码,错误是您没有保留每个单元格状态。我修好了。查看状态天。
有很多方法可以做到这一点,在我的解决方案中,我使用了 Set
这给了 O(1)
复杂性
在设置、添加和删除切换日期时,这正是您所需要的:
import React, { Component } from "react";
import "./DayNames.css";
export default class DayNames extends Component {
constructor(props) {
super(props);
this.state = {
bgColor: "lightslategrey",
toggledDays: new Set()
};
}
createDayId = (columnIndex, rowIndex) => `${columnIndex}-${rowIndex}`;
handleClick = (columnIndex, rowIndex) => {
this.setState(prevState => {
const prevToggledDays = prevState.toggledDays;
const dayId = this.createDayId(columnIndex, rowIndex);
if (this.isDayToggled(columnIndex, rowIndex)) {
prevToggledDays.delete(dayId);
} else {
prevToggledDays.add(dayId);
}
return { toggledDays: prevToggledDays };
});
};
isDayToggled = (columnIndex, rowIndex) => {
const dayId = this.createDayId(columnIndex, rowIndex);
return this.state.toggledDays.has(dayId);
};
render() {
//Getting number of days of month
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
const numberDaysOfMonth = new Date(year, month, 0).getDate();
let foo1 = [];
for (let i = 1; i <= numberDaysOfMonth; i++) {
foo1.push(i);
}
let foo2 = ["Ops1", "Ops2", "Ops3", "Ops4", "Ops5", "Ops6"];
const ops = foo2.map((elem, columnIndex) => {
return (
<div className="ops_header" key={columnIndex}>
{elem}
{foo1.map((cell, rowIndex) => {
return (
<div
className="operator"
data-id={cell}
key={rowIndex}
onClick={() => this.handleClick(columnIndex, rowIndex)}
>
{this.isDayToggled(columnIndex, rowIndex) ? "Holiday" : cell}
</div>
);
})}
</div>
);
});
return (
<div>
<div className="table">{ops}</div>
</div>
);
}
}
然而有时依赖索引是危险的,但它似乎适合你的情况
希望对您有所帮助<3
好像你在切换时正在获取单元格的所有索引,我添加了另一个参数,它基本上是你的 foo2
的索引,并将切换条件从一个索引更改为两个 [i= foo1, i=foo2];
// This line changed from e => (e,index)
handleClick = (e, index) => {
// memories both index and put into one variable
const target = [e, index];
console.log(target);
this.setState(prevState => ({
// update state
isToggleOn: { ...prevState.isToggleOn, [target]: !prevState.isToggleOn[target] }
}));
};
let foo2 = ["Ops1", "Ops2", "Ops3", "Ops4", "Ops5", "Ops6"];
const ops = foo2.map((elem, index) => {
return (
<div className="ops_header" key={index}>
{elem}
{foo1.map((cell, i) => {
return (
<div
className="operator"
data-id={cell}
key={i}
// pass both indexes to handleClick();
onClick={() => this.handleClick(i, index)}
>
// togle based on indexes;
{this.state.isToggleOn[[i, index]] ? "Holiday" : cell}
</div>
);
})}
</div>
);
});