【问题标题】:Toggle one list item instead of entire list切换一个列表项而不是整个列表
【发布时间】:2019-06-19 20:43:52
【问题描述】:

我正在制作一张列出广播电台的卡片,当您单击一个电台时,该列表项的图片会下拉。我从 json 中提取的所有数据。

我已尝试在 toggle.jsapp.js 文件中构建列表

app.js-- div 带切换功能(全部在卡片内..许多 div)

           <div class="card-trip-infos">
              <div>
               <Toggle />
              </div>
              <img class="card-trip-user avatar-bordered"/>
            </div>

toggle.js 渲染块:

    state = {
        on: false,
    }
    toggle = () => {
      this.setState({
      on: !this.state.on
      })
    }
    render() {
        return (
          <ul>
              <div>
                  <p>{PostData.radios[0].name}</p>
                  {PostData.radios.map((postDetail, index) => {
                    return <div>
                    <li onClick={this.toggle}>
                      <span id='radioName'>{postDetail.name}</span> <span id='frequency'>{postDetail.frequency}</span>

                    </li>
                    {
                      this.state.on &&  <img src='imagesrc'></img>
                    }


                    </div>
                  })}
              </div>

          </ul>
        )
      }
    }

我不知道到底出了什么问题,但我希望能够分别为每个列表行切换图片。我很困惑在哪里迭代我的 json 以及在哪里插入所有内容。

非常感谢!!

【问题讨论】:

  • 嗨!当您提出问题时,文本区域右侧有一个 如何格式化 框,其中包含有用的信息。还有一个工具栏,里面装满了格式化辅助工具。还有一个 [?] 按钮提供格式化帮助。 一个预览区域,显示您的帖子发布后的样子,位于文本区域和“发布您的问题”按钮之间(这样您就必须滚动过去才能找到该按钮,以鼓励你看它)。使您的帖子清晰,并证明您花时间这样做,可以提高您获得好答案的机会。
  • 您不会正确切换数据,而是根据列表中的选择获取数据,对吧?
  • @Neil 我相信我确实想切换数据。但我也想根据选择获取数据。假设我点击第一个列表项,我想获取(切换)第一个列表项的图片。现在如果我点击第一个列表项,我会得到每个列表项的图片(每个列表项都会切换,下面是图片)。
  • toggle 有什么状态?你能显示切换功能吗??????????
  • @Neil 我刚刚为你编辑了主帖,谢谢!

标签: javascript reactjs


【解决方案1】:

由于我们不知道您的切换功能和所有组件,我们无法给出准确的建议,但为了在此处执行您想要的操作(只需切换所选项目),您有两种不同的方法。

  1. 您可以将选定状态保留在组件本身中。

class App extends React.Component {
  state = {
    cards: [
      { id: 1, name: "foo" },
      { id: 2, name: "bar" },
      { id: 3, name: "baz" }
    ],
  };

  render() {
    const { cards } = this.state;
    return (
      <div>
        {cards.map(card => (
          <Card
            key={card.id}
            card={card}
          />
        ))}
      </div>
    );
  }
}

class Card extends React.Component {
  state = {
    selected: false
  };

  handleSelect = () =>
    this.setState(state => ({
      selected: !state.selected
    }));

  render() {
    const { card } = this.props;
    return (
      <div
        className={this.state.selected ? "selected" : ""}
        onClick={this.handleSelect}
      >
        {card.id}-{card.name}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
.selected {
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />
  1. 您可以在父组件中保持选中状态。

class App extends React.Component {
  state = {
    cards: [
      { id: 1, name: "foo" },
      { id: 2, name: "bar" },
      { id: 3, name: "baz" }
    ],
    selected: {}
  };

  handleSelect = id =>
    this.setState(state => ({
      selected: { ...state.selected, [id]: !state.selected[id] }
    }));

  render() {
    const { cards, selected } = this.state;
    return (
      <div>
        {cards.map(card => (
          <Card
            key={card.id}
            card={card}
            handleSelect={this.handleSelect}
            selected={selected[card.id]}
          />
        ))}
      </div>
    );
  }
}

const Card = ({ card, handleSelect, selected }) => {
  const handleClick = () => handleSelect(card.id);
  return (
    <div className={selected ? "selected" : ""} onClick={handleClick}>
      {card.id}-{card.name}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
.selected {
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />

【讨论】:

  • 嘿,我在主帖中添加了状态函数。但是谢谢你的回答!我不知道我可以使用这样的状态..我会进一步研究您当前的解决方案。
  • 我喜欢这个,但我会考虑将 selected 移动到卡片状态,因为两个状态属性都绑定到同一个索引。卡片也应该传播card.name没有意义..
  • @derric-d,分别映射您的项目,然后像我在这里一样保持每个项目的状态。因此,您可以管理每个项目的切换状态。否则,您的切换状态会影响我认为的所有项目。 @Neil,有时将状态保留在父级中可能很有用。可能不适用于此示例,但有一些用例。这就是我提供这两种解决方案的原因:) 我不明白card.name 传播部分?顺便说一句,感谢key 我忘记了的建议:)
  • 不用担心?我认为上面还有另一个关键.. 传播评论是因为不需要卡片道具你已经在卡片的上下文中,如果你花钱那么你可以解构我们的@ 987654330@ 和 id 很容易。
  • 关于您所做的状态评论的注释。就个人而言,我会映射数据并添加一个三元表达式来更新/更改所选属性,否则只需返回数组中的当前项目。这将使订单按预期保持。
【解决方案2】:

为单个列表项创建一个组件,在那里有一个状态,它将保存一个布尔属性来判断图像是否要显示。渲染函数看起来像这样:

render (
  return (
    <li onClick="this.toggleShowImage()">
      <div> {props.data.name} </div>
      <div> {props.data.frequency} </div>
      {this.state.showImage ? <img src='imageUrl' /> : null }
     </li>
  )
)

然后在 toggle.js 中遍历您的数据并创建列表组件。渲染函数如下所示:

render() {
  return (
    <ul>
       {PostData.radios.map((postDetail, index) => {
          return <ListItem key={postDetail.name} data={postDetail} />
       })}
    
    </ul>
   )
}

【讨论】:

  • 我真的很喜欢这个答案,但是我必须改变我的状态函数吗?我在我的主要帖子中使用渲染功能添加了它。感谢您的回答!
  • @derric-d 您不需要更改该功能。在我的解决方案中,只需将功能“toggleShowImage”替换为您的“toggle”功能,它就会起作用。另外,将属性名称“showImage”(我使用的)替换为“on”(您正在使用)。
  • 这个 ListItem 元素是什么?我收到一个错误,说它是未定义的。我还把你写的第一个渲染块放在 App.js 中吗?还是它自己的组件?谢谢!
  • nvm 我看到你在上面说组件的地方:P 谢谢你的回复!
  • @derric-d 欢迎 :) 如果它有助于解决您的问题,请您接受我的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2016-09-16
  • 2017-10-01
相关资源
最近更新 更多