0

I have a problem with React.js. This is the line of code I have:

import React, { useState } from "react";
import { map } from "lodash";

function Steps({ procedure, commandSender, index }) {
  const [selected, setSelected] = useState([]);

  function clickHandler(command, key, index) {
    commandSender(`${command}`)
    if (isSelected((index-key))) setSelected(selected.filter(s => s !== (index-key)))
    else ([...selected, (index-key)])
  }

  function isSelected(key) {
    return selected.includes(key);
  }

  return (
    <>
      {procedure.guide &&
        map(procedure.guide, (key) => (
          <a
            key={`${index}-${key}`}
            className={`bt-blue ${isSelected(index-key) ? "active" : ""}`}
            onClick={() => clickHandler('GUIDE', key, index)}
          >
            {procedure.title}
          </a>
        ))
      }
      {procedure.success &&
        map(procedure.success, () => (
          <a
            key={`${index}-${key}`}
            className={`bt-green ${isSelected(index-key) ? "active" : ""}`}
            onClick={() => clickHandler('SUCCESS', key, index)}
          >
            {procedure.title}
          </a>
        ))
      }
    </>
  );
}

export default Steps;

As you can see, I map a procedure, and for each item, I create an A tag, that calls a function clickHandler. This function calls another function and a setSelected. The setSelected function says which A tag is clicked or not. The only problem is that when I click in an A tag, it doesn't get selected.

But I need just the tag I clicked to have a SELECTED effect. I think for you guys it's a very easy error to correct, but I'm really a newbie with React. Please help.

2
  • There is no difference between link's except their innerTexts. You should give them a unique key or something unique and use this to understand which one was clicked. Is that clear? Commented Jul 7, 2020 at 14:27
  • Ok, I gave then an unique Key. But how do I use this key to understand which one was clicked? Commented Jul 7, 2020 at 14:31

1 Answer 1

1

I believe the problem is the data structure you are using for storing selected values. Right now, it's a plain boolean, and you are dealing with an array.

You could do the following:

First, we change the selected to an array.

const [selected, setSelected] = useState([]);

Then, how can we identify each procedure in a unique way? Do they have an ID? By Title? Command? Let's suppose it's by title.

function clickHandler(title, command) {
    commandSender(`${command}`)

    if(selected.includes(title)) {
        setSelected(selected.filter(s => s !== title)) // we unselected our procedure
    } else {
        setSelected([...selected, title]) // we add our procedure to the selected
    }
}

Finally, you should change the rendering of your procedures, and remove the useEffect, as it's unnecessary.

          <a
            className={`bt-green ${selected.includes(procedure.title) ? "active" : ""}`}
            onClick={() => clickHandler(procedure.title, 'SUCCESS')}
          >
            {procedure.title}
          </a>

Furthermore, you could create a function to determine if your procedure is selected, so you don't have to write every time selected.includes... :

function isSelected(procedure) {
   return selected.includes(procedure);
}
Sign up to request clarification or add additional context in comments.

9 Comments

That was very good explained. But now, all the items are selected and I cant unselect them. I used a key value, instead of the title. But I don't think thats the problem.
Making the modifications above should do the work. Can you post your modified code in your answer or create a sandbox?
These are the two functions and the useEffect: const [selected, setSelected] = useState(false); useEffect(()=>{ setSelected(selected) },[selected]) function clickHandler(command, key) { commandSender(${command}) if (isSelected(key)) setSelected(selected.filter(s => s !== key)) else ([...selected, key]) } function isSelected(procedure) { return selected.includes(procedure); }
Where is your key coming from? And you should remove the useEffect statement as well.
I'll edit the question, sou you can see what i've changed. Now, no tags are being selected
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.