如何显示/隐藏array.map()项

问题描述 投票:1回答:3

我想根据isCommentShown state属性显示/隐藏JSX的一部分。但由于此部分位于地图循环内,因此isCommentShown不仅对当前所有映射项目起作用。因此,当我在toggleComment中显示/隐藏循环内的每个注释时。我想这可以通过将所有内容移动到一个单独的组件来解决,因为每个组件都有自己的状态。但我想知道如果没有那个我能否解决这个问题。

const SearchResults = () => {
  const [isCommentShown, setIsCommentShown] = useState(false);

  const toggleComment = () => {
    setIsCommentShown(!isCommentShown);
  };

  return (
    <>
      {props.search_results.map(obj =>
        <div key={obj.id}>
          { obj.comment ? <img onClick={toggleComment}/> : null }
          <div>{obj.text}</div>
          { isCommentShown ? <p>{obj.comment}</p> : null }
        </div>
      )}
    </>
  );
};
reactjs react-hooks
3个回答
1
投票

您可以使用useState钩子创建一个对象,该对象将所有搜索结果ID保存为键,并使用布尔值指示是否应显示注释。

const { useState, Fragment } = React;

const SearchResults = props => {
  const [shownComments, setShownComments] = useState({});

  const toggleComment = id => {
    setShownComments(prevShownComments => ({
      ...prevShownComments,
      [id]: !prevShownComments[id]
    }));
  };

  return (
    <Fragment>
      {props.search_results.map(obj => (
        <div key={obj.id}>
          {obj.comment ? (
            <button onClick={() => toggleComment(obj.id)}>Toggle</button>
          ) : null}
          <div>{obj.text}</div>
          {shownComments[obj.id] ? <p>{obj.comment}</p> : null}
        </div>
      ))}
    </Fragment>
  );
};

ReactDOM.render(
  <SearchResults
    search_results={[
      { id: 0, text: "Foo bar", comment: "This is rad" },
      { id: 1, text: "Baz qux", comment: "This is nice" }
    ]}
  />,
  document.getElementById("root")
);
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

1
投票

如果您只希望一次显示一条评论,则必须存储评论ID以显示,而不是存储true或false。唯一标识要扩展的项目非常重要

const SearchResults = () => {
  const [commentShown, setCommentShown] = useState({});

  const toggleComment = (id) => {
    setCommentShown(prev => Boolean(!prev[id]) ? {...prev, [id]: true} : {...prev, [id]: false});
  };

  return (
    <>
      {props.search_results.map(obj =>
        <div key={obj.id}>
          { obj.comment ? <img onClick={() => toggleComment(obj.id)}/> : null }
          <div>{obj.text}</div>
          { commentShown[id] ? <p>{obj.comment}</p> : null }
        </div>
      )}
    </>
  );
};

如果您需要同时打开多个注释,则可以维护开放ID的映射

const SearchResults = () => {
  const [commentShown, setCommentShown] = useState('');

  const toggleComment = (id) => {
    setCommentShown(prev => prev.commentShown !== id? id: '');
  };

  return (
    <>
      {props.search_results.map(obj =>
        <div key={obj.id}>
          { obj.comment ? <img onClick={() => toggleComment(obj.id)}/> : null }
          <div>{obj.text}</div>
          { commentShown === obj.id ? <p>{obj.comment}</p> : null }
        </div>
      )}
    </>
  );
};

1
投票

使用id来定位所需注释的切换。

更准确地说,使用状态来存储显示/隐藏值,并将id传递给onclick事件以精确切换要注释的注释。这应该做的工作:

class SearchResults extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    for (let result of props.search_results) {
      this.state[`${result.id}IsShown`] = true;
    }
  }
  toggleComment(id) {
    let key = `${result.id}IsShown`;
    this.setState({[key]: !this.state[key]});
  }
  render() {
    return (
      <>
        {this.props.search_results.map(result =>
          <div key={result.id}>
            {
              result.comment
              ? <img onClick={() => toggleComment(result.id)}/>
              : null
            }
            <div>{result.text}</div>
            { isCommentShown ? <p>{obj.comment}</p> : null }
          </div>
        )}
      </>
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.