猿问

如何使用 React apollo-client 缓存搜索数组?

我有一个简单的搜索组件和 handleSearch 功能:


  const { data, loading, error } = useQuery(QUERY_GET_ELEMENTS);

  const client = useApolloClient();


   <input

     onChange={handleSearch}

     placeholder="&#128270;  Search..."

   />


  function handleSearch(e) {

    const { value } = e.target;


    const matchingElements = data.filter(({ name }) =>

      name.toLowerCase().includes(value.toLowerCase())

    );


    client.writeData({

      data: {

        elements: matchingElements

      }

    });

  }



  // rendering the elements looks something like this:


  data.elements.map(el => <div>{el.name}</div>

数据来自一个 useQuery 钩子。


问题是搜索只在一个方向上起作用,因为一旦过滤了元素,我就会丢失原始列表。我需要保留所有可以过滤的元素的存储,并在保留原始列表的同时仅渲染过滤后的元素。


我正在使用 apollo 进行状态管理,但似乎无法使其正常工作。我的第一个想法是使用 client.writeData 复制元素并且永远不会被修改,但是这并没有按预期工作。


任何帮助深表感谢。


郎朗坤
浏览 130回答 1
1回答

收到一只叮咚

您应该能够使用useState钩子来完成此操作。这个例子对我有用:import React, { useState, useEffect } from 'react';import gql from 'graphql-tag';import { useQuery } from '@apollo/react-hooks'const QUERY_GET_ELEMENTS = gql`&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; elements {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }`;export default function Test() {&nbsp; &nbsp; const [isDisplayDataSet, setIsDisplayDataSet] = useState(false);&nbsp; &nbsp; const [displayData, setDisplayData] = useState([]);&nbsp; &nbsp; const { data, loading, error } = useQuery(QUERY_GET_ELEMENTS);&nbsp; &nbsp; useEffect(() => {&nbsp; &nbsp; &nbsp; &nbsp; if (!loading && !isDisplayDataSet) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setDisplayData(data.elements);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setIsDisplayDataSet(true);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }, [isDisplayDataSet, displayData, data, loading])&nbsp; &nbsp; function handleSearch(e) {&nbsp; &nbsp; &nbsp; &nbsp; const { value } = e.target;&nbsp; &nbsp; &nbsp; &nbsp; const matchingElements = data.elements.filter(({ name }) =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name.toLowerCase().includes(value.toLowerCase())&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; setDisplayData(matchingElements);&nbsp; &nbsp; }&nbsp; &nbsp; if (error) {&nbsp; &nbsp; &nbsp; &nbsp; console.error(error);&nbsp; &nbsp; &nbsp; &nbsp; return <h1>There was an error</h1>&nbsp; &nbsp; }&nbsp; &nbsp; if (isDisplayDataSet) {&nbsp; &nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <input&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; className="form-control mb-3"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onChange={handleSearch}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; placeholder="&#128270;&nbsp; Search..."&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ul className="list-group">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {displayData.map(el => <li className="list-group-item" key={el.id}>{el.name}</li>)}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ul>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </>&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; return '';&nbsp; &nbsp; }}我为样式添加了一些引导类:)这是我设置的快速而肮脏的阿波罗服务器,用于加载一些数据:const { ApolloServer } = require('apollo-server');const gql = require('graphql-tag');const fetch = require('node-fetch');const typeDefs = gql`&nbsp; &nbsp; type Element {&nbsp; &nbsp; &nbsp; &nbsp; id: ID!&nbsp; &nbsp; &nbsp; &nbsp; name: String!&nbsp; &nbsp; }&nbsp; &nbsp; type Query {&nbsp; &nbsp; &nbsp; &nbsp; elements: [Element]!&nbsp; &nbsp; }&nbsp; &nbsp; schema {&nbsp; &nbsp; &nbsp; &nbsp; query: Query&nbsp; &nbsp; }`;const resolvers = {&nbsp; &nbsp; Query: {&nbsp; &nbsp; &nbsp; &nbsp; async elements() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const res = await fetch('https://reqres.in/api/users');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const { data } = await res.json();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const elements = data.map(({ id, first_name, last_name }) => ({ id, name: `${first_name} ${last_name}` }))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('elements', elements);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return elements;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}const server = new ApolloServer({&nbsp; &nbsp; typeDefs,&nbsp; &nbsp; resolvers});server.listen().then(({ url }) => {&nbsp; &nbsp; console.log('server ready on ' + url);});
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答