我的祖父母不是 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();
};
希望对大家有所帮助^^
所以,我 运行 遇到了这个问题,我在使用一个 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();
};
希望对大家有所帮助^^