Javascript 能够在每个面板上选择一个项目,而无需删除面板上的选择

Javascript 能够在每个面板上选择一个项目,而无需删除面板上的选择,javascript,reactjs,Javascript,Reactjs,我有一个react应用程序,其中我有一个companyDashboard,它有三个孩子CompanyPanel 我有一个名为data的状态,它位于companyesdashboard中,是一个由三个对象组成的数组,每个对象都有一个时隙数组 当我点击任何一个时隙时,它会变成红色,如果另外两个公司面板中的任何一个也有相同的时隙,它们就会变成灰色 假设我点击第一个公司面板上的第一个时隙,它变为红色,而另一个公司面板上的相同时隙变为灰色 如果我点击第二个公司面板上的第二个时隙,它会相应地变为红色,而其他

我有一个react应用程序,其中我有一个
companyDashboard
,它有三个孩子
CompanyPanel

我有一个名为
data
的状态,它位于
companyesdashboard
中,是一个由三个对象组成的数组,每个对象都有一个
时隙数组

当我点击任何一个
时隙时,它会变成红色,如果另外两个
公司面板中的任何一个也有相同的
时隙,它们就会变成灰色

假设我点击第一个
公司面板上的第一个时隙,它变为红色,而另一个
公司面板上的相同时隙变为灰色

如果我点击第二个
公司面板上的第二个时隙,它会相应地变为红色,而其他公司面板上匹配的时隙会正确地变灰

但是上一个选定的时隙,即第一个
CompanyPanel
上的第一个时隙将被重置,并将其默认颜色设置为黑色

我希望这样,每个
公司面板
都可以选择一个
时隙
,只要它不是相同的
时隙
,例如,我可以在第一个
公司面板
的12:00选择一个,在第二个
公司面板
的13:00选择另一个。但不是都在12点

这是州所在的公司仪表盘:

我还有一个代码,你可以在那里看到它:


导出默认类CompaniesDashboard扩展React.Component{
建造师(道具){
超级(道具)
此.state={
数据,
selectedTime:“无”,
所选公司:“无”
}
this.chooseTime=this.chooseTime.bind(this)
}
选择时间(选择时间、名称){
这是我的国家({
selectedTime:selectedTime.dateUTCString,
所选公司:名称
})
}
render(){
const{data,error,selectedTime,selectedCompany}=this.state
返回(
{this.isLoading()&&&p>正在加载

} {error&{error}

} {data&&data.map({times,name,_id},i)=>( ))} ) } }
这是公司面板:

export default (props) => {
  const { selectedTime, times, chooseTime, deleteTime, name, selectedCompany } = props

  const colorClass = (time) => {
    let color = null;

    if (time.dateUTCString === selectedTime) {
      color = 'gray'
      if (name === selectedCompany) {
        color = 'red'
      }
    } 
    return color;
  }

  return (
    <React.Fragment>
      <div className="flex-auto pa3">
        <div className="ba mv2">
          <p className="tc pa2 dib bg-near-white">{props.name}</p>
        </div>
        <div className="ba mv2">
          <p className="tc pa2 dib bg-red white">{selectedTime}</p>
        </div>
        <div className="ba mv2 bg-light-gray">
          {times.map((time, i) => (
            <div key={i} className="bg-almost-white">
              <span className='pa2 red pointer ma2 bg-white' onClick={() => deleteTime(time, name)}>X</span>
              <p
                onClick={() => chooseTime(time, name)}
                className={`tc pa2 dib pointer ${colorClass(time, selectedCompany)}`}>
                {time.dateUTCString}
              </p>
            </div>
          ))}
        </div>
      </div>
    </React.Fragment>
  )
}
导出默认值(道具)=>{
const{selectedTime,times,choosetTime,deleteTime,name,selectedCompany}=props
const colorClass=(时间)=>{
设color=null;
如果(time.dateUTCString===selectedTime){
颜色=‘灰色’
如果(名称===所选公司){
颜色=‘红色’
}
} 
返回颜色;
}
返回(

{props.name}

{selectedTime}

{times.map((时间,i)=>( deleteTime(时间,名称)}>X

chooseTime(时间、名称)} className={`tc pa2 dib指针${colorClass(时间,selectedCompany)}`> {time.dateUTCString}

))} ) }
我看到了您的代码,根据我的理解,一旦您选择了任何公司下的时间,您将根据时间和公司名称直接应用颜色类,这将不会帮助您同时保留其他公司下的时间段

为了实现这一点,我认为您应该在state对象中保留旧状态

this.state = {
  data,
  selectedTime: 'None',
  selectedCompany: 'None',
  prevData:{}
}
// Your chooseTime function will be something like this
chooseTime (selectedTime, name) {
this.setState({
  prevState: ...this.state,
  selectedTime: selectedTime.dateUTCString,
  selectedCompany: name
 })
}
现在,在您的colorClass()函数中呈现公司面板组件之前,在应用灰色和红色颜色类之前,您可以在状态对象内部检查您正在与prevState对象映射的时间,在哪个公司面板中您需要保持红色,哪个是灰色。它将帮助您显示在不同公司面板下保留的多个时间段


希望这有帮助。我只是想说抱歉,没有提供完整的代码。:)

您的状态配置就是问题所在。您有3个公司,但您的状态只有一个
selectedTime
和一个
selectedCompany
,因此,当您选择时间和公司时,所有3个公司都会调用其colorClass函数(因为selectedTime和selectedCompany道具会发生更改,从而导致重新渲染),所有颜色都会重置为“null”(默认为黑色)然后只剩下新的selectedTime和selectedCompany

有两种方法可以解决这个问题,我的方法可能是保留两个阵列—一个用于多次,另一个用于选定的公司。时间数组可能是常量,正如您所说,您希望能够标记特定的时间段,并且对于每个时间段,您在另一个数组中都有匹配的索引,以填充选择它的公司

然后将该数组传递给每个公司面板,并在colorClass中迭代公司数组。如果单元格中包含公司名称-它将相应的时隙标记为红色,如果其另一个公司名称-灰色,如果其为空-黑色


如果公司选择另一个时隙,也不要忘记清空当前占用的单元格。

谢谢@Gibor,但你所说的“时间数组可能是常量”是什么意思?你的意思是我应该提前用所有时隙填充aray?我不太明白你所说的“每个时隙在另一个数组中都有匹配的索引”是什么意思,你能再解释一下吗?非常感谢!是的,当然:第一个问题-是的,如果这与你的程序是如何工作的。显然,如果你从外部来源获得时间,或者自己生成时间,并且时间可以改变,那么时间就不会是常数。如果它们无论如何都是相同的-最好构建一个常量时间数组,这样就知道它们不应该被更改。对于第二个问题-我的意思是,您创建的公司数组的长度与时间数组的长度相同,因此公司[0]将保留n
this.state = {
  data,
  selectedTime: 'None',
  selectedCompany: 'None',
  prevData:{}
}
// Your chooseTime function will be something like this
chooseTime (selectedTime, name) {
this.setState({
  prevState: ...this.state,
  selectedTime: selectedTime.dateUTCString,
  selectedCompany: name
 })
}