【问题标题】:make only the clicked item on a list active in react仅使列表中单击的项目在反应中处于活动状态
【发布时间】:2021-01-15 05:06:39
【问题描述】:

这可能真的很简单,我想在用户单击项目时显示列表项的信息,但是,我拥有的代码将在单击时打开所有列表项的信息。

https://codesandbox.io/s/friendly-lichterman-j1vpd?file=/src/App.js:0-599

import React, { useState } from "react";
import "./styles.css";

const list = [1, 2, 3];
export default function App() {
  const [active, setActive] = useState(false);

  return (
    <div>
      {list.map((item, idx) => {
        return (
          <>
            <li
              onClick={() => {
                setActive(!active);
              }}
            >
              {item}
              <div className={active ? "active" : "info"}>
              {" "}
              Info {idx + 1}
            </div>
            </li>
            
          </>
        );
      })}
    </div>
  );
}



【问题讨论】:

  • 因为您为所有项目设置了相同的活动挂钩

标签: javascript reactjs


【解决方案1】:

您正在尝试仅切换所有项目都使用的活动状态。而是使用索引位置来切换。

我已经使用 cmets 解释了代码中的其余部分。

App.js

import React, { useState } from "react";
import "./styles.css";

const list = [1, 2, 3];
export default function App() {
  const [active, setActive] = useState();

  return (
    <div>
      {/* You forgot to add ul here */}
      <ul>
        {list.map((item, idx) => {
          return (
            // Added key to each child to avoid error. Use <React.Fragment/> instead of <>
            <React.Fragment key={idx}>
              <li
                onClick={() => {
                  // Condition for toggling the lists.
                  // If current list is selected
                  if (active === idx) {
                    // change active to blank
                    setActive();
                  } else {
                    // change active to current index
                    setActive(idx);
                  }
                }}
              >
                {item}
              </li>
              <div className={active === idx ? "info active" : "info"}>
                {" "}
                Info {idx + 1}
              </div>
            </React.Fragment>
          );
        })}
      </ul>
    </div>
  );
}

编辑了这个 css 以避免应用到另一个标签 样式.css

.info.active {
  display: flex;
}

你可以在沙盒上试试上面的代码 https://codesandbox.io/s/stackoverflow-qno-65730790-tmeyf

【讨论】:

    【解决方案2】:

    似乎是useReducer 的一个很好的用例。这是一个非常有用的工具来跟踪多个组件的状态。在您的情况下,您需要跟踪给定的 LI 是否处于活动状态(显示信息)。以下是使用useReducerSanbdox 的方法

    import React, { useState } from "react";
    import "./styles.css";
    
    const list = [1, 2, 3];
    const default_states = list.map((item) => Object({ id: item, action: false }));
    export default function App() {
      const [li_states, dispatch] = React.useReducer((state, id) => {
        return state.map((item) => {
          if (item.id === id) return { id: item.id, active: !item.active };
          else return item;
        });
      }, default_states);
    
      return (
        <div>
          {list.map((item) => {
            const cur = li_states.find((s) => s.id === item);
            return (
              <div key={item}>
                <li
                  onClick={() => {
                    dispatch(item);
                  }}
                >
                  {item}
                </li>
                <div className={cur.active ? "action" : "info"}> Info {item}</div>
              </div>
            );
          })}
        </div>
      );
    }
    
    

    这里发生的情况是,每次单击任何 LI 时,dispatch 使用 LI 的 ID 调用 React.useReducer 内部的 reducer 函数并切换单击的 LI 的状态。

    【讨论】:

      【解决方案3】:

      你也可以按照这个方法

      const list = ['Start', 'Installation', 'Text Banners', 'Image Banners'];
      const links = ['/start', '/installation', '/textbanners', '/imagebanners'];
        
        const [active, setActive] = useState(null)
        const toggleActive = (e) => {
          console.log(e)
          setActive(e.target.innerText)
        }
        return (
          <div className={style.dashboard_container}>
            <div className={style.dashboard}>
              <ul>
                {list.map((item, index) => {
                  return (
                    <li className={active == item ? style.active : ''} key={index} onClick={toggleActive}>{item}</li>
                  )
                })}
              </ul>
            </div>
            {children}
          </div>
        );
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 2013-07-26
      • 1970-01-01
      • 2018-10-30
      • 1970-01-01
      • 2016-09-21
      • 1970-01-01
      相关资源
      最近更新 更多