Как показать / скрыть элемент array.map () - PullRequest
0 голосов
/ 24 февраля 2019

Я хочу показать / скрыть часть JSX в зависимости от isCommentShown свойства свойства.Но поскольку эта часть находится внутри цикла карты, 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>
      )}
    </>
  );
};

Ответы [ 3 ]

0 голосов
/ 24 февраля 2019

Используйте идентификатор для выбора нужного комментария.

Точнее, используйте состояние для хранения значений show / hide и передайте идентификатор событию 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>
        )}
      </>
    );
  }
}
0 голосов
/ 24 февраля 2019

Вы можете использовать хук useState для создания объекта, который будет хранить все идентификаторы результатов поиска в качестве ключей и логическое значение, указывающее, должен ли быть показан комментарий.

Пример

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>
0 голосов
/ 24 февраля 2019

Вместо того, чтобы хранить 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>
      )}
    </>
  );
};

. Если вам нужно открыть несколько комментариев одновременно, вы можете сохранить карту открытых идентификаторов

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>
      )}
    </>
  );
};
.
...