#Toggle data in React

27 messages · Page 1 of 1 (latest)

grim phoenix
#

https://codesandbox.io/s/angry-cray-d7l17s?file=/src/App.js

Hello guys. I have a table that displays some data. In the Market Status column, each cell shows either “Suspended” or “Released”. What I want to do is when I click that Change Status button in a specific cell, the string would change from “Suspended” to “Released” and if I clicked again, it would change from “Released” to “Suspended” (basically toggle these two strings) Can someone help me to achieve that functionality? I’ve spent quite some times now but I still couldn’t figure it out. Thanks

angry-cray-d7l17s by electroence1 using loader-utils, react, react-dom, react-scripts

latent blade
#

You just want to change it client side even though it’s not really doing anything?

grim phoenix
#

yes that's correct

#

just want to have that functionality. it doesn't need to alter the original data

latent blade
#

you're re-using data in too many places

#

you define it as a state variable

  const [data, setData] = useState(propsData);

but then re-use this in several places:

  const getSuspended = (data) => {
    return datas.filter((data) =>
    altData.forEach((data) => {

even if things "work", it is going to eventually cause you pain. you really should rename your variables to something unique and clear. data, altData, datas, etc. are very-much not clear. 🙂

grim phoenix
#

you're absolutely right. I was gonna clean it up after I can implement the toggle functionality

#

sorry for the confusion

latent blade
#
<button id={`btn-change-${idx}`} onClick={changeStatus}>change status</button>
  const changeStatus = (event) => {
    const playerIndex = Number(event.target.id.replace('btn-change-', ''));
    const playerData = filterableData[playerIndex];
    
    // you need to call setData() here, but you don't have an easy way to match filterableData to data.
    // you should add an actual key/id to each entry of data so you know which one it is.
  };
#

no, it's finding the entry you're trying to change

#

you then need to modify data

#

is status per-player or per entry in data?

grim phoenix
#

it's per-player

latent blade
#

oh that makes it much easier

grim phoenix
#

is there anyway you could add it to the codesandbox so i can see it more clearly?

latent blade
#
  const changeStatus = (event) => {
    const playerId = Number(event.target.id.replace('btn-change-', ''));
    setData(prevData => {
      const newData = [];
      for (const pd of prevData) {
        if (pd.playerId === playerId) {
          newData.push({ ...pd, suspended: pd.suspended === 'Suspended' ? 'Released' : 'Suspended' });
        } else {
          newData.push(pd);
        }
      }
      return newData;
    });
  };
<button id={`btn-change-${data.playerId}`} onClick={changeStatus}>change status</button>
#

or using .map():

  const changeStatus = (event) => {
    const playerId = Number(event.target.id.replace('btn-change-', ''));
    setData(prevData => prevData.map(pd => {
      if (pd.playerId === playerId) {
        return { ...pd, suspended: pd.suspended === 'Suspended' ? 'Released' : 'Suspended' };
      }
      return pd;
    }));
  };
grim phoenix
#

this totally works. but if we want per-entry instead, then it gets a little complicated, because we don't have the unique id for each entry, correct?

latent blade
#

yes. just create an ID for each original entry when first creating data and use those everywhere

grim phoenix
latent blade
#
const [data, setData] = useState(propsData.map((d, i) => ({ dataId: i, ...d })));
<button id={`btn-change-${data.dataId}`} onClick={changeStatus}>change status</button>
  const dataId = Number(event.target.id.replace('btn-change-', ''));
...
    if (pd.dataId === dataId) {
...
#

obviously you would use something better than the index for IDs in a "real" application (usually coming from a database)

grim phoenix
latent blade
#

it can, I was missing ()'s (I edited the above code to fix it)

grim phoenix
#

gotcha

#

it works as expected

#

thank you soooo much for taking your time helping me with this!!!