Отфильтровать список на основе ввода - PullRequest
2 голосов
/ 28 мая 2020
const App = () => {
  const [searchTerm, setSearchTerm] = React.useState('');
  const stories = [
    ...
  ];

  const handleSearch = event => {
    setSearchTerm(event.target.value);
  };

  const searchStories = stories.filter((story) => {
    return story.title.includes(searchTerm);
  })

  return (
    <div>
      <h1>My Hacker Stories</h1>
      <Search onSearch={handleSearch}/>
      <hr />
      <List list={searchStories}/>
    </div>
  );
};

const Search = (props) =>{

  return (
    <div>
      <label htmlFor="search"><strong>Search:</strong></label> { ' '}
      <input id='search' type='text' onChange={props.onSearch}/>
    </div>
  );

};


const List = ({list}) =>
  list.map((item) =>
     (
      <div key={item.objectID}>
        <span>
          <a href={item.url}>{item.title}</a>
        </span>
        <span>{item.author}</span>
        <span>{item.num_comments}</span>
        <span>{item.points}</span>
      </div>
    )
  )

Я пытаюсь отфильтровать компонент списка на основе ввода поиска. Это работает, если я не введу поисковый запрос в поле ввода. Когда я пытаюсь найти элемент, список пуст, ничего не отображается, это пустой список, однако ошибка не отображается.

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

Я немного изменил ваш код, чтобы создать работающий фрагмент, который вы можете изменить обратно на свой код,

просто нужно добавить другое состояние для searchStories и использовать useEffect для фильтрации, когда searchTerm изменяется следующим образом:

* Щелкните Run Code Snippet и введите h, чтобы увидеть, как работает фильтр

const App = () => {
  const [searchTerm, setSearchTerm] = React.useState("");
  const [searchStories, setSearchStories] = React.useState([]);
  const stories = ["hello", "hi", "bye", "have a good day"];

  const handleSearch = event => {
    setSearchTerm(event.target.value);
  };

  React.useEffect(() => {
    setSearchStories(
      stories.filter(story => {
        return story.includes(searchTerm);
      })
    );
  }, [searchTerm]);

  return (
    <div>
      <h1>My Hacker Stories</h1>
      <Search onSearch={handleSearch} />
      <hr />
      <List list={searchStories} />
    </div>
  );
};

const Search = props => {
  return (
    <div>
      <label htmlFor="search">
        <strong>Search:</strong>
      </label>{" "}
      <input id="search" type="text" onChange={props.onSearch} />
    </div>
  );
};

const List = ({ list }) =>
  list.map(item => (
    <div key={item}>
      {item}
      {/* <span>
        <a href={item.url}>{item.title}</a>
      </span>
      <span>{item.author}</span>
      <span>{item.num_comments}</span>
      <span>{item.points}</span> */}
    </div>
  ));

const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);
<div id="root"></div> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
0 голосов
/ 28 мая 2020

Функция фильтра проверяет, присутствует ли searchTerm в заголовке нашей статьи, но она все еще слишком категорична в отношении регистра букв. Если мы ищем «реагировать», в вашем отображаемом списке нет отфильтрованной истории «Реагировать». Чтобы решить эту проблему, мы должны ввести нижний регистр в заголовке статьи и в searchTerm.

const App = () => {
  ...

  const searchedStories = stories.filter(function(story) {
    return story.title
      .toLowerCase()
      .includes(searchTerm.toLowerCase());
  });

  ...
};
...