Javascript 如何在react中从嵌套映射迭代切换单个元素

Javascript 如何在react中从嵌套映射迭代切换单个元素,javascript,reactjs,loops,class,toggle,Javascript,Reactjs,Loops,Class,Toggle,我是新来的。我正在进行一个为工人创建轮班轮班表的项目。创建了一个包含单元格的网格。当你点击一个单元格时,它将把它的值从天数改为“假日”,如果你再次点击它,它将变回天数。问题是当我单击一个单元格时,整行单元格的值都会改变。如何仅更改一个单元格的值 这是我的密码 export default class DayNames extends Component { constructor(props) { super(props); this.state = { isTo

我是新来的。我正在进行一个为工人创建轮班轮班表的项目。创建了一个包含单元格的网格。当你点击一个单元格时,它将把它的值从天数改为“假日”,如果你再次点击它,它将变回天数。问题是当我单击一个单元格时,整行单元格的值都会改变。如何仅更改一个单元格的值

这是我的密码

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>
    );
  }
}
导出默认类DayNames扩展组件{
建造师(道具){
超级(道具);
此.state={
是的
};
}
handleClick=e=>{
this.setState(prevState=>({
isToggleOn:{…prevState.isToggleOn[e]:!prevState.isToggleOn[e]}
}));
};
render(){
//正在获取月的天数
const month=新日期().getMonth()+1;
const year=新日期().getFullYear();
const numberDaysOfMonth=新日期(年、月、0)。getDate();
设foo1=[];
for(设i=1;i{
返回(
{elem}
{foo1.map((单元格,i)=>{
返回(
这个.handleClick(i)}
>
{this.state.isToggleOn[i]?“Holiday”:cell}
);
})}
);
});
返回(
{ops}
);
}
}
这是指向沙盒…/components/DayNames/DayNames.js的链接

试试这个代码沙盒

或者查看下面更新的组件

import React,{Component}来自“React”;
导入“/DayNames.css”;
导出默认类DayNames扩展组件{
foo2=[“Ops1”、“Ops2”、“Ops3”、“Ops4”、“Ops5”、“Ops6”];
建造师(道具){
超级(道具);
const month=新日期().getMonth()+1;
const year=新日期().getFullYear();
此.state={
bgColor:“浅灰色”,
//是的,
天数:数组(this.foo2.length)
.fill(0)
.map(x=>Array(新日期(年、月、0).getDate()).fill(0))
};
}
handleClick=(索引,i)=>{
const{days}=this.state;
天[索引][i]=!天[索引][i];
这是我的国家({
天
});
};
render(){
//正在获取月的天数
const month=新日期().getMonth()+1;
const year=新日期().getFullYear();
const numberDaysOfMonth=新日期(年、月、0)。getDate();
设foo1=[];
for(设i=1;i{
返回(
{elem}
{foo1.map((单元格,i)=>{
返回(
this.handleClick(index,i)}
>
{this.state.days[index][i]?“Holiday”:cell}
);
})}
);
});
返回(
{ops}
);
}
}

我已经更新了代码,错误是你没有保持每个细胞的状态。我已经修好了。检查状态中的天数。

有很多方法可以做到这一点,在我的解决方案中,我使用了
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>
    );
  }
}

import React,{Component}来自“React”;
导入“/DayNames.css”;
导出默认类DayNames扩展组件{
建造师(道具){
超级(道具);
此.state={
bgColor:“浅灰色”,
toggledDays:新集合()
};
}
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);
}否则{
prevToggledDays.add(dayId);
}
返回{toggledDays:prevToggledDays};
});
};
isDayToggled=(columnIndex,rowIndex)=>{
const dayId=this.createDayId(columnIndex,rowIndex);
返回this.state.toggledDays.has(dayId);
};
render(){
//正在获取月的天数
const month=新日期().getMonth()+1;
const year=新日期().getFullYear();
const numberDaysOfMonth=新日期(年、月、0)。getDate();
设foo1=[];
for(设i=1;i{
返回(
{elem}
{foo1.map((单元格,行索引)=>{
返回(
this.handleClick(columnIndex,rowIndex)}
>
{this.isDayToggled(columnIndex,rowIndex)?“Holiday”:cell}
);
})}
);
});
返回(
{ops}
);
}
}
然而,有时依赖索引是危险的,但它似乎适合您的情况


希望它有帮助似乎你在切换时正在获取单元格的所有索引,我添加了另一个参数,基本上是你的
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] }
    }));
};
让foo2=[“Ops1”、“Ops2”、“Ops3”、“Ops4”、“Ops5”、“Ops6”];
常量操作=foo2.map((元素,索引)=>{
返回(
{elem}
{foo1.map((单元格,i)=>{
返回(
this.handleClick(i,index)}
>
//基于索引的togle;
{this.state.istogleon[[i,index]]?“Holiday”:cell}
);
})}
);
});

您可以为此创建多维数组。这样地:
    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>
      );
    });