0

Screenshot

I want to render a settings menu onclick when an element is added to my list and disable all other setting menus when one is active. I also have a sample element in a different state and would like to deactivate all setting menus when it is on and have it disabled if a settings menu is on. I am storing the setting states of all elements in an array and in my update function the copy of my setting state is changing but my actual settings state isn't. I think it has to do with my useeffect and when I comment it out my settings state does change but it isn't rendered. It was working before I mapped my chart data, but I am not sure what caused it to stop working as commenting it out still does not render settings.

const [settings, setSettings] = useState([]);
const [sampSettings, setSampSettings] = useState(false);

const updateSettings = (val, index) => {
if(val){
    let copySettingsFalse = [...settings]
    copySettingsFalse[index]=false;
    return setSettings(copySettingsFalse);
}
let copySettingsTrue = settings.fill(false);
copySettingsTrue[index] = true;
console.log(copySettingsTrue)
return setSettings(copySettingsTrue);

};

useEffect(() => {
if (stockList.length>0){
stockList.map((val,index) => {
  // Chart
  setLineData([
    ...lineData,
    {
      labels:trimLineDataHistory[index],
      datasets: [
        {
          label: val.Tick,
          data: trimLineDataHistory[index].reverse(),
          pointRadius: 0,
          fill: false,
          backgroundColor: day ? "#e9dfd4" : "#141e28",
          borderColor: "#52ad59",
        },
      ],
    },
  ]);
  // Settings
  setSettings([...settings, false]);
})}
  return;
},[stockList]);

// Settings
// useEffect(() => {
//   if (settings.includes(true)) {
//     setSampSettings(false);
//   }
//   if (sampSettings === true) {
//     setSettings(settings.fill(false));
//   }
//   return;
// }, [settings,sampSettings]);

  if(stockList.length>1)
  return(
  <>
  {stockList.map((val, index) => {
   const { Tick, Name } = val;
   return(
   <div className="stockItemIcon">
        <BsFillGearFill
         className="gearIcon"
         onClick={() => updateSettings(settings[index], index)}></BsFillGearFill>

             
        <div className={settings[index]?
        (day?"settingsContainerAlt showSettings daySettings":"settingsContainerAlt showSettings nightSettings")
       :(day?"settingsContainerAlt hideSettings daySettings":"settingsContainerAlt hideSettings nightSettings")}>

            </div>)}
            </>)
deepakchethan
  • 5,240
  • 1
  • 23
  • 33
nomac10
  • 23
  • 5
  • I found you use `let copySettingsTrue = settings.fill(false);` to get a new copy, `fill` method return a modified array rather than a new one. Maybe you can change to `let copySettingsTrue = [...settings].fill(false);` – Huan Nov 16 '21 at 05:08
  • After doing as @DukeLuo said, I think you should probably add `settings` in the dependency array of your `useEffect`. – Blessing Nov 16 '21 at 05:16
  • That seems to have solved it! Could you explain why a new array has to be returned instead of a modified one? My thinking with a modified array is that I could set all settings to false and then set a specific index to true and then set my settings to the modified array. – nomac10 Nov 16 '21 at 05:17
  • @Blessing Adding settings to my useeffect leads to infinite rendering – nomac10 Nov 16 '21 at 05:24
  • @nomac10 Modify state directly is a bad practice, you can use [this reference](https://stackoverflow.com/a/40309023/12814009) to get the detail reason. – Huan Nov 16 '21 at 10:33

1 Answers1

0

You try to add the "Key" attribute BsFillGearFill tag and also set & update value for it. it may be any value

Karan Ekkawala
  • 317
  • 1
  • 11