Есть ли способ повторно выполнить запрос GraphQl, когда пользователь нажимает кнопку, которая направляет его на другой URL-адрес, используя тот же запрос (но разные переменные)? Например, home
передает переменную "/", которая отображает определенные компоненты. Качество передает переменную "/ качество", которая отображает другие компоненты.
На данный момент у меня есть панель навигации, которая использует ссылки React для перехода пользователей на разные страницы (например, «Главная страница», «Контакты», «Качество» и т. Д. c.). Эти разные целевые страницы используют один и тот же запрос graphQL, но то, что отображается, зависит от переменной, передаваемой в запрос. Ссылки в настоящее время переходят на правильный URL-адрес, но содержимое не изменяется (до тех пор, пока страница не обновится). Я предполагаю, потому что запрос graphQL не обновляется или не обновляется, пока страница не обновляется.
Как мне это сделать?
Мой домашний компонент (который на самом деле может быть лучше назван как общая целевая страница (потому что многие разные страницы могут использовать его повторно). Этот компонент передает переменную URL в запрос graphql.
import React, { useEffect } from 'react';
// TODO: Convert the components to Lazy Load ~~~~~~~~~~~~~~~~~~
import Hero from './Hero';
import Features from './Features';
import Testimonials from './Testimonials';
import ContentSideImage from './ContentSideImage';
import Layout from './Layout';
import NotImplemented from '../shared/NotImplemented';
import { useSelector } from 'react-redux';
import BlogTeaser from './BlogTeaser';
import { FETCH_GRAPH } from '../../redux/actions/contentActions';
import { byIdLoadingKey } from '../../util/redux';
import ProductTeaser from './ProductTeaser';
import ImageSplit from './ImageSplit';
import HeroCarousel from './HeroCarousel';
import SectionIntro from './SectionIntro';
import IconBanner from './IconBanner';
import FullWidthImage from './FullWidthImage';
import Button from './Button';
import PictureContentPicture from './PictureContentPicture';
import MetaProductCardSection from './MetaProductCardSection';
export const ContentTypeMap = {
'/component/hero': Hero,
'/component/two-column': ContentSideImage,
'/component/feature-list': Features,
'/component/testimonials': Testimonials,
'/component/blog_teaser': BlogTeaser,
'/component/product-teaser': ProductTeaser,
'/component/imagesplit': ImageSplit,
'/component/componentherocarousel': HeroCarousel,
'/component/sectionintro': SectionIntro,
'/component/iconbanner': IconBanner,
'/component/fullwidthimage': FullWidthImage,
'/component/button': Button,
'/component/picturecontentpicture': PictureContentPicture,
'/component/metaproductcard': MetaProductCardSection,
};
export default function Home(props) {
const URL = `/site/website${props.match.url}/index.xml`.replace(/\/\//g, '/')
console.log(URL)
const content = useSelector(state => state.content.home);
const persona = useSelector(state => state.users.persona);
useEffect(
() => {
if (content) {
window.amplify && window.amplify.publish('INIT_ICE_REGIONS');
}
},
[content]
);
return (
<Layout
className="landing__home-page"
variables={{
post: [
{ name: 'ageGroup', type: 'String', value: persona ? persona.age : null },
{ name: 'gender', type: 'String', value: persona ? persona.gender : null },
{ name: 'slug', type: 'String', value: null },
{ name: 'limit', type: 'Int', value: 3 },
{ name: 'URL', type: 'String', value: URL }
]
}}
requirements={[
'home',
{
name: 'post',
getter: (content) =>
(content.loading[byIdLoadingKey(FETCH_GRAPH, 'home')] === false) ? content.post : null
}
]}
>
{
content && content.map((component) => {
const Component = ContentTypeMap[component.contentType] || NotImplemented;
return <Component key={component.objectId || component.localId} {...component} />
})
}
</Layout>
);
}
Мои маршруты. js file:
import React, { useContext, useEffect } from 'react';
import { Route, Switch } from 'react-router-dom';
import ProductListing from './app/ProductsListing';
import ProductDetails from './app/ProductDetails';
import LogIn from './app/LogIn';
import Register from './app/Register';
import Home from './app/Home';
import NotFound404 from './app/NotFoundView';
import CartView from './app/CartView';
import Account from './app/Account';
import CheckoutView from './app/CheckoutView';
import { AddressEntry } from './app/AddressCard';
import OrderDetails from './app/OrderDetails';
import BlogRoll from './app/BlogRoll';
import BlogEntry from './app/BlogEntry';
import Search from './app/Search';
import { __RouterContext } from 'react-router';
import { useSelector } from 'react-redux';
import Quality from './app/Quality';
const Routes = () => {
const { history } = useContext(__RouterContext);
const { isAuthoring } = useSelector(state => state.theme);
useEffect(
() => {
if (isAuthoring) {
return history.listen((location) => {
window.require &&
window.require(['guest'], (guest) => {
guest.reportNavigation(location, location.pathname);
});
});
}
},
[isAuthoring]
);
return (
<Switch>
{/* <Route exact path="/" component={Home}/> */}
<Route path="*" component={Home} />
<Route exact path="/quality" component={Quality} />
<Route exact path="/catalog" component={ProductListing}/>
<Route path="/catalog/:product" component={ProductDetails}/>
<Route path="/cart" component={CartView}/>
<Route path="/checkout" component={CheckoutView}/>
<Route exact path="/account/address-book/new" component={AddressEntry}/>
<Route exact path="/account/address-book/edit/:id?" component={AddressEntry}/>
<Route exact path="/account/orders/:id" component={OrderDetails}/>
<Route path="/account/:tab?" component={Account}/>
<Route exact path="/blog" component={BlogRoll}/>
<Route path="/blog/:slug" component={BlogEntry}/>
<Route path="/login" component={LogIn}/>
<Route path="/register" component={Register}/>
<Route path="/search" component={Search}/>
<Route path="/" component={NotFound404}/>
{/* <Route path="*" component={DynamicRoute} /> */}
</Switch>
);
};
export default Routes;
The home.fragment.graphql
#import "./Hero.fragment.graphql"
#import "./ContentSideImage.fragment.graphql"
#import "./FeatureList.fragment.graphql"
#import "./Testimonials.fragment.graphql"
#import "./BlogTeaser.fragment.graphql"
#import "./ImageSplit.fragment.graphql"
#import "./HeroCarousel.fragment.graphql"
#import "./SectionIntro.fragment.graphql"
#import "./IconBanner.fragment.graphql"
#import "./FullWidthImage.fragment.graphql"
#import "./Button.fragment.graphql"
#import "./PicContentPic.fragment.graphql"
#import "./MetaProductCard.fragment.graphql"
fragment Home on craftercms_site {
home: page_landing {
items {
localId(filter: {equals: $URL})
sections_o {
item {
key
value
component {
contentType: content__type
... on component_hero {
...Hero
}
... on component_two__column {
...ContentSideImage
}
... on component_feature__list {
...FeatureList
}
...on component_testimonials {
...Testimonials
}
... on component_blog_teaser {
...BlogTeaser
}
... on component_product__teaser {
objectId
title_s
numOfProducts_i
}
... on component_imagesplit {
...ImageSplit
}
... on component_componentherocarousel {
...HeroCarousel
}
... on component_sectionintro {
...SectionIntro
}
... on component_iconbanner {
...IconBanner
}
... on component_fullwidthimage {
...FullWidthImage
}
... on component_button {
...Button
}
... on component_picturecontentpicture {
...PicContentPic
}
... on component_metaproductcard {
...MetaProductCard
}
}
}
}
}
}
}
The Home.graphql
# import "./Header.fragment.graphql"
# import "./Nav.fragment.graphql"
# import "./Home.fragment.graphql"
# import "./Footer.fragment.graphql"
# import "./Metafooter.fragment.graphql"
query Home($URL: String) {
...Post
...Header
...Nav
...Home
...Footer
...Metafooter
}