简体   繁体   English

过滤数组并在 React 中显示结果

[英]Filter array and show results in React

I am trying to filter my results via button onClicks in React, but for some reason its not working?我正在尝试通过 React 中的按钮 onClicks 过滤我的结果,但由于某种原因它不起作用?

https://stackblitz.com/edit/react-x7tlxr?file=src/App.js https://stackblitz.com/edit/react-x7tlxr?file=src/App.js

import React, {useEffect, useState} from "react";
import axios from 'axios';
import "./style.css";

export default function App() {

  const [fetchData, setFetchData] = useState([]);
  const [loading, setLoading] = useState(true);
  const [isError, setIsError] = useState(false);

  const url = 'https://jsonplaceholder.typicode.com/todos';

  useEffect(() => {
      let mounted = true;
      const loadData = async () => {
          try {
              const response = await axios(url);
              if (mounted) {
                  setFetchData(response.data);
                  setLoading(false);
                  setIsError(false);
                  console.log('data mounted')
              }
          } catch (err) {
              setIsError(true)
              setLoading(false);
              setFetchData([]);
              console.log(err);
          }
      };
      loadData();
      return () => {
          mounted = false;
          console.log('cleaned');
      };
  },
      [url]
  );
  

  const renderdata = () => {
    if (fetchData) {
      return (
        <div>{fetchData.map(inner => {
          return (
            <React.Fragment key={inner.id}>
            <p>{inner.title}</p>
            </React.Fragment>
          )
        })}</div>
      )
    } else {
      <p>No data to display!</p>
    }
  }

  const handle1 = () => {
    const result1 = fetchData.filter((inner) => inner.id === '1');
    setFetchData(result1);
  }

  const handle2 = () => {
    const result2 = fetchData.filter((inner) => inner.id === '2');
    setFetchData(result2);
  }

  const handleAll = () => {
    setFetchData(fetchData);
  }


  return (
    <div>
      <button onClick={handleAll}>Show all</button>
      <button onClick={handle1}>Filter by id 1</button>
      <button onClick={handle2}>Filter by id 2</button>
      {renderdata()}
    </div>
  );
}

The id is a number, not a string, so you filter(s) need to be changed like that: id是一个数字,而不是一个字符串,因此您需要像这样更改过滤器:

const result1 = fetchData.filter((inner) => inner.id === 1);

You have another problem, is that you change the whole data set when you filter, so once you've filtered, you can't "unfilter" or filter again on another id.您还有另一个问题,即您在过滤时更改了整个数据集,因此一旦过滤,您就无法“取消过滤”或在另一个 ID 上再次过滤。

You need to maintain the original fetchedData unchanged.您需要保持原始fetchedData不变。

This example shows how it can be fixed.示例显示如何修复它。

I found 2 issues in your code我在您的代码中发现了 2 个问题

  1. Id in the API result is numeric not string inner.id === '2' . API 结果中的 Id 是数字而不是字符串inner.id === '2' so this will return false inner.id === 2 you need to use like this所以这将返回 false inner.id === 2你需要像这样使用

  2. when you assign the filtered value to the original array it will of course change the original array so when you try to filter it second time you don't have the original API result in the fetch data array because it is already filtered So i have created one more array filteredData This will work.当您将过滤后的值分配给原始数组时,它当然会更改原始数组,因此当您尝试第二次过滤它时,获取数据数组中没有原始 API 结果,因为它已经被过滤了所以我创建了多一个数组filteredData这会起作用。

     import React, {useEffect, useState} from "react"; import axios from 'axios'; import "./style.css"; export default function App() { const [fetchData, setFetchData] = useState([]); const [filteredData, setFileredData] = useState([]); const [loading, setLoading] = useState(true); const [isError, setIsError] = useState(false); const url = 'https://jsonplaceholder.typicode.com/todos'; useEffect(() => { let mounted = true; const loadData = async () => { try { const response = await axios(url); if (mounted) { setFetchData(response.data); setFileredData(response.data) setLoading(false); setIsError(false); console.log('data mounted') } } catch (err) { setIsError(true) setLoading(false); setFetchData([]); console.log(err); } }; loadData(); return () => { mounted = false; console.log('cleaned'); }; }, [url] ); const renderdata = () => { if (filteredData) { return ( <div>{filteredData.map(inner => { return ( <React.Fragment key={inner.id}> <p>{inner.title}</p> </React.Fragment> ) })}</div> ) } else { <p>No data to display!</p> } } const handle1 = () => { const result1 = fetchData.filter((inner) => inner.id === 1); setFileredData(result1); } const handle2 = () => { const result2 = fetchData.filter((inner) => inner.id === 2); setFileredData(result2); } const handleAll = () => { setFileredData(fetchData); } return ( <div> <button onClick={handleAll}>Show all</button> <button onClick={handle1}>Filter by id 1</button> <button onClick={handle2}>Filter by id 2</button> {renderdata()} </div> ); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM