【问题标题】:How to filter an array with fetched data in React js?如何在 React js 中使用获取的数据过滤数组?
【发布时间】:2021-06-25 01:46:43
【问题描述】:

我正在尝试通过在输入中输入用户编号来过滤获取的博客文章。此数字应与帖子 userId 匹配,并仅显示该给定用户“撰写”的帖子(这是一个从 1 到 10 的数字,每个用户有 10 个帖子)。

问题:当我在输入中输入数字时,帖子会消失并且不会过滤任何内容。我很确定我被过滤功能卡住了。

提前致谢!

function App(pst) {

  const [posts, setPosts] = useState([]);
  const [query, setQuery] = useState('');

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts/')
      .then(response => response.json())
      .then(json => setPosts(json))
  }, [])

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      
      <Router>
          <NavBar />
          <Switch>
            <Route exact path='/'>
              <Home />
              <SearchBar 
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              />
              <Grid container spacing={2} justify='center'>
                {posts.filter((val) => {
                  if (query === '') {
                    return val
                  } else if (query === val.userId) {
                    return val
                  }
                  console.log(query);
                }).map((pst) => (
                  <PostCard pst={pst} key={pst.id}/>
                ))}
              </Grid>
            </Route>
            <Route exact path='/singlePost/:postId' component={SinglePost} />
            <Route exact path='/PostList'>
              <PostList pst={pst}/>
            </Route>
          </Switch>
      </Router>
    </ ThemeProvider>
  );
}

【问题讨论】:

    标签: reactjs filter frontend fetch mapping


    【解决方案1】:

    过滤数据的方式主要有两种:客户端或服务器端。有时,在处理大型数据集和复杂数据结构时,服务器端的性能会更高。在您的示例中,数据非常小,数据结构非常平坦,因此客户端过滤就绰绰有余了。

    首先,由于您希望向客户端显示的所有数据都被过滤,因此您需要将该数据存储到它自己的posts 状态。然后,您将拥有某种searchValue 状态,只要用户更改input 值,该状态就会发生变化。利用这两种状态,您可以使用searchValue 过滤posts,并将结果存储到它自己的filteredPosts 状态。

    React 只会在 stateprops 更改时重新渲染组件。因此,您需要利用状态更改来使您的组件保持最新状态。

    工作演示

    代码

    App.js

    import * as React from "react";
    import "./styles.css";
    
    export default function App() {
      const [searchValue, setSearch] = React.useState(0);
      const [posts, setPosts] = React.useState([]);
      const [filteredPosts, setFilteredPosts] = React.useState([]);
    
      const handleSearchChange = (event) => {
        /*
          This "handleSearchChange" is a callback function that accepts an
          "event" as an argument. 
    
          This "event" contains the "input" DOM element. And this
          element contains a "value" property that is stored as 
          a string on the "target" property. This "event.target.value"
          will update the input's "searchValue" state.
    
          Please note, "event.target.value" will be a string and when
          filtering the post's "id", which is a number, a string value of "1" 
          won't equal a post id of number 1! Therefore, parseInt(string, 10)
          coverts the string value to a number value.
        */
        setSearch(parseInt(event.target.value, 10));
      };
    
      const handleSearchReset = () => {
        setSearch(0);
      };
    
      React.useEffect(() => {
        fetch("https://jsonplaceholder.typicode.com/posts")
          .then((response) => response.json())
          .then((json) => setPosts(json));
      }, []);
    
      React.useEffect(() => {
        /*
          When the searchValue changes, filter the posts by id with
          searchValue and store the result to "filteredPosts"
        */
        setFilteredPosts(posts.filter((post) => post.id === searchValue));
      }, [posts, searchValue]);
    
      return (
        <div className="App">
          <h1>Search Posts</h1>
          <input
            min={0}
            value={searchValue}
            type="number"
            onChange={handleSearchChange}
          />
          <br />
          <button type="button" onClick={handleSearchReset}>
            Reset Search
          </button>
          <h1>Filtered Posts</h1>
          <pre className="code">
            <code>{JSON.stringify(filteredPosts, null, 2)}</code>
          </pre>
          <h1>Available Posts</h1>
          <pre className="code">
            <code>{JSON.stringify(posts, null, 2)}</code>
          </pre>
        </div>
      );
    }
    

    index.js

    import * as React from "react";
    import ReactDOM from "react-dom";
    import App from "./App";
    
    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById("root")
    );
    
    

    【讨论】:

      猜你喜欢
      • 2021-06-30
      • 2020-01-21
      • 2019-07-11
      • 2020-09-15
      • 2021-10-04
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多