我的祖父母不是 re-rendering 在通过 useState() 更改状态后使用新变量和显示新数据的查询

My Grandparent is not re-rendering the Query with new variables and displaying new data, after the state changes through useState()

所以,我 运行 遇到了这个问题,我在使用一个 graphql 查询的同时制作过滤器。有一个 child、parent 和 grandparent(这些是不同的组件)。现在我的查询在其中使用了变量,最​​初在加载时我在 useState 中设置了变量并且它工作正常。现在,当我单击一个复选框(这是内部 Child 组件)时,它会将其数据(对于新查询而言是变量)传递给 Grandparent 并且我得到了它,所以我将该数据传递给查询变量。但这不是 re-redering 使用新变量再次查询。所以我的过滤器不起作用。

盛大Parent

// handling all the product grid actions and data
function ProductGrid() {

  const [queryVariables, setQueryVariables] = useState({first: 20});
  console.log(queryVariables);
  // get the variable object

  
  const { loading, error, data, fetchMore} = useQuery(QUERY, {
    variables: queryVariables
  });

   
  if (loading) return <p>Loading...</p>;
  if (error) return (
    <p>
    {console.log(error)}
    </p>
  );

  let productEdges = data.products.edges;
  return(
    <div className="outContainer">
      {/* <PriceFilter/> */}
      <TypeFilter getFilters={queryVariables => setQueryVariables(queryVariables)} />
      {/* test button */}
      <div className="product-grid">
        {productEdges.map((element, index) => {
          
          // formatting the price
          let tempPrice = Math.floor(element.node.priceRange.minVariantPrice.amount);
          let productPrice = new Intl.NumberFormat().format(tempPrice);

          return(
              <div className="container" key={index}>
                <div className="image-container">
                  <img src={element.node.images.edges[0].node.transformedSrc} alt={element.node.title} />
                </div>
                <div className="product-title">{element.node.title}</div>
                <div>{element.node.priceRange.minVariantPrice.currencyCode}. {productPrice}</div>
              </div>

          ) 
        })}
      </div>
      {/* load more products button */}
      <button
        className="load-more"
        onClick={()=>{
          const endCursor = data.products.edges[data.products.edges.length - 1].cursor;
          
          fetchMore({
            variables: {
              after: endCursor,
              queryVariables
            }
          })
        }}>
          Load More
        </button>
    </div>
  )
}

// graphql query for products fetching
const QUERY = gql`
query productFetch($first:Int, $after:String, $query:String){
  products(first:$first, after: $after, query:$query){
    edges{
      node{
        priceRange{
          minVariantPrice{
            amount
            currencyCode
          }
        }
        title
        images(first:1){
          edges{
            node{
              transformedSrc(maxWidth: 300)
            }
          } 
        }
        
      }
      cursor
    }
    pageInfo{
      hasNextPage
    }
  }
}

`

Parent

// ************** Parent ***************
function TypeFilter(props) {
  // assume other code is here for a modal pop and 
     accordion inside here
  
  // passing the prop to checkbox component here and 
     getting back new state which we use as a callback for 
     it's parent
  <TypeCheckBox getCheckState={queryVariables => 
  props.getFilters(queryVariables)} />
}

Child

// ************** Child *****************
let result = "";
let variables = 
  {
    first: 28,
    query: ""
  };
function TypeCheckBox(props){
  // below function returns variables for apollo query
    const handleCheckChange = (event) => {
        setState({ ...state, [event.target.name]: event.target.checked });
        if(event.target.checked){
            // pass this value into the productGrid component
            if(counter > 1){
              result += "&";
            }
            result = `${result}product_type:${event.target.value}`;
            counter++;
            // setting filter type to result
            console.log(result);
            variables.query = result;
            console.log(variables);
            return props.getCheckState(variables);
        }else{

          result = result.replace(`product_type:${event.target.value}`, "");
          result = removeLast(result, "&");
          counter--;
          // setting filter type to result
          console.log(`in else ${result}`);
          variables.query = result;
          console.log(variables);
          return props.getCheckState(variables);
        }
    };
  

}
  return (
            <FormGroup column>
              <FormControlLabel
                control={<Checkbox checked={state.checkedBridal} value="Bridal" onChange={handleCheckChange} name="checkedBridal" />}
                label="Bridals"
              />
  )
}

我尝试在 GrandParent 的 useQuery 上使用 useEffect,但是返回的常量在外部无法访问,比如

    useEffect(() => { 
    const { loading, error, data, fetchMore} = useQuery(QUERY, {
        variables: queryVariables
      });
  }, [queryVariables])

非常感谢您的回答^^

所以,我想出了一个解决方案,因为没有人回答,所以我要回答。

首先需要在useQuery hook中添加refetch和fetch-policy as

const { loading, error, data, fetchMore, refetch, networkStatus } = useQuery(
QUERY,
{
  variables: queryVariables,
  // notifyOnNetworkStatusChange: true,
  fetchPolicy: "network-only"
}
);

然后您需要创建一个与传递给 children 的 props 同名的单独函数,并使用带 queryVariables 的扩展运算符来扩展和重新获取查询,并使用新变量作为

const getFilters = queryVariables => {
 setQueryVariables({ ...queryVariables });
 refetch();
};

希望对大家有所帮助^^