HJW
HJW

Reputation: 1032

function variable not being passed to setState correctly

Granted, I have been away from React for a while, but this should be more in the category of plain JS.

I have the following setState function:

// click event on parent for performance reasons
``Component:``
const [active, setActive] = useState({ "": false });
return (
  <div onClick={handleClick}>
     <List>{items}</List>
  </div>
)

And the click event:

const handleClick = event => {
    const item = event.target;
    const li = item.classList;
    const attr = item.attributes.listid.value;

    li.toggle("selected");
    // Why is attr not getting used correctly?
    setActive({ attr: !active });
  };

The variable attr is not being used in the setState event. "Attr is assigned a value but never used". When I console.log(useState) after the click function I see {attr: false} (before it's null: false).

Why is the variable not being used, and how do I use it correctly?

Upvotes: 0

Views: 58

Answers (3)

Akram Badah
Akram Badah

Reputation: 427

Why not separate the item list in its own component and then render it in your List component like this:


const ListItem = ({item}) => {
  const [active, setActive] = useState(false);

  const handleClick =() => {
    active ? setActive(false) : setActive(true);
  };

  return (
    <li className={active ? 'selected' : ''}>{item}</li>
  )
}
// click event on parent for performance reasons
``Component:``
const [active, setActive] = useState(false);
return (
  <div onClick={handleClick}>
     <List>{items.map((item) => (<ListItem item={item} />))}</List>
  </div>
)

and active itself will toggle to true or false.

Upvotes: 0

Joseph D.
Joseph D.

Reputation: 12174

before it's null: false

The initial value of active is { "": false } as indicated in your useState.

Why is the variable not being used, and how do I use it correctly?

The code isn't using active state.

To use it when interacting with the list items, you can have something like:

const [active, setActive] = useState({});

const handleClick = event => {
  // ... get item ...
  const attr = item.attributes.listid.value;

  setActive({ [attr]: !active[attr] });
};

const renderList = (items) => {
  return (
    <List>
      {items.map((item) => <Item active={active[item.attr]} />)}
    </List>
  );
};

return (
  <div onClick={handleClick}>
    {renderList(items)}
  </div>
);

Upvotes: 1

Code Maniac
Code Maniac

Reputation: 37755

Things i will change is first use a proper name for key instead of ""

const [active, setActive] = useState({ active: false });

If you intended to just toggle boolean valule we don't need attr at all

setActive({ active: !active });

Why attr "Attr is assigned a value but never used" ?

setActive({ attr: !active });

This line is adding a property named attr ( just plain string ) but not using the attr variable, so you're getting "Attr is assigned a value but never used"

If you intended to use attr variable's value as key's name you need to use computed property accessor []

 setActive({ [attr]: !active });

Upvotes: 1

Related Questions