Javascript 在盖茨比浏览器中使用GraphQL数据?

Javascript 在盖茨比浏览器中使用GraphQL数据?,javascript,node.js,reactjs,graphql,gatsby,Javascript,Node.js,Reactjs,Graphql,Gatsby,我有一个应用程序,它有一些我手动定义的路线ID(基本上是一个长SPA中的一堆部分)。我在gatsby browser.js中获取它们,并将它们与shouldUpdateScroll一起使用,检查路线ID是否存在,在这种情况下,滚动到路线/路段的位置 例如: export const shouldUpdateScroll = ({ routerProps: { location } }) => { const container = document.querySelector('.si

我有一个应用程序,它有一些我手动定义的路线ID(基本上是一个长SPA中的一堆部分)。我在
gatsby browser.js
中获取它们,并将它们与
shouldUpdateScroll
一起使用,检查路线ID是否存在,在这种情况下,滚动到路线/路段的位置

例如:

export const shouldUpdateScroll = ({ routerProps: { location } }) => {
  const container = document.querySelector('.site')
  const { pathname } = location
  
  const projectRoutes = [`project1`, `project2`]
  if (projectRoutes.indexOf(pathname) !== -1) {
      const target = document.getElementById(pathname)
      container.scrollTop = target.offsetTop; 
  }

  return false
}
这对我的用例很有效

现在我想为动态创建内容(从Sanity获取)的页面添加类似的内容。据我所知,我无法在
gatsby browser.js
中使用GraphQL,那么,将ID从santy获取到
gatsby browser.js
的最佳方法是什么,以便我可以使用它们来识别它们的滚动位置


如果有其他更好的方法来达到同样的效果,我当然愿意接受。

我认为你把问题复杂化了。您不需要使用
gatsby browser.js
来实现它

  • 首先,因为您直接访问DOM对象(使用
    document.getElementById
    ),并且您正使用React创建一个虚拟DOM,以避免指向真实的DOM。直接攻击真实DOM(如jQuery)会对应用程序的性能产生巨大影响,并可能导致一些问题,因为在SSR(SServer-SideRendering)中可能尚未创建元素

  • 您正在对文件上的逻辑部分(id)进行硬编码,而该文件并不打算这样做

我认为使用一个简单的函数,使用几个钩子,就可以获得完全相同的结果

您可以使用钩子获得与document.getElementById相同的信息,并在需要时滚动到该位置

const YourComponent= (props) => {
  const sectionOne = useRef(null);
  const sectionTwo = useRef(null);

  useEffect(()=>{
   if(typeof window !== `undefined`){
    console.log("sectionOne data ",sectionOne.current)
    console.log("sectionTwo data ",sectionTwo.current)
      if(sectionOne) window.scrollTo( 0, 1000 ); // insert logic and coordinates 
   }
  }, [])   

  return (
    <>
      <section ref={sectionOne}>Section 1</section>
      <section ref={sectionTwo}>Section 2</section>
    </>
  );
}
constyourcomponent=(道具)=>{
const sectionOne=useRef(null);
const section2=useRef(null);
useffect(()=>{
如果(窗口类型!=`undefined`){
console.log(“sectionOne数据”,sectionOne.current)
console.log(“Section2数据”,Section2.current)
if(section1)window.scrollTo(0,1000);//插入逻辑和坐标
}
}, [])   
返回(
第一节
第二节
);
}
您可以将该函数隔离到一个单独的文件中,以便接收一些参数并返回一些其他参数以实现所需的功能。基本上,上面的代码片段为每个部分创建了一个引用,一旦加载了DOM树(
useffect
with empty
deps
[]
),就可以根据您的逻辑执行一些操作


您的
文档.getElementById
被替换为
第一节.current
(注意
.current
),最初设置为
null
,以避免在重新隐藏时发生卸载或缓存问题。

我认为您的问题过于复杂。您不需要使用
gatsby browser.js
来实现它

  • 首先,因为您直接访问DOM对象(使用
    document.getElementById
    ),并且您正使用React创建一个虚拟DOM,以避免指向真实的DOM。直接攻击真实DOM(如jQuery)会对应用程序的性能产生巨大影响,并可能导致一些问题,因为在SSR(SServer-SideRendering)中可能尚未创建元素

  • 您正在对文件上的逻辑部分(id)进行硬编码,而该文件并不打算这样做

我认为使用一个简单的函数,使用几个钩子,就可以获得完全相同的结果

您可以使用钩子获得与document.getElementById相同的信息,并在需要时滚动到该位置

const YourComponent= (props) => {
  const sectionOne = useRef(null);
  const sectionTwo = useRef(null);

  useEffect(()=>{
   if(typeof window !== `undefined`){
    console.log("sectionOne data ",sectionOne.current)
    console.log("sectionTwo data ",sectionTwo.current)
      if(sectionOne) window.scrollTo( 0, 1000 ); // insert logic and coordinates 
   }
  }, [])   

  return (
    <>
      <section ref={sectionOne}>Section 1</section>
      <section ref={sectionTwo}>Section 2</section>
    </>
  );
}
constyourcomponent=(道具)=>{
const sectionOne=useRef(null);
const section2=useRef(null);
useffect(()=>{
如果(窗口类型!=`undefined`){
console.log(“sectionOne数据”,sectionOne.current)
console.log(“Section2数据”,Section2.current)
if(section1)window.scrollTo(0,1000);//插入逻辑和坐标
}
}, [])   
返回(
第一节
第二节
);
}
您可以将该函数隔离到一个单独的文件中,以便接收一些参数并返回一些其他参数以实现所需的功能。基本上,上面的代码片段为每个部分创建了一个引用,一旦加载了DOM树(
useffect
with empty
deps
[]
),就可以根据您的逻辑执行一些操作


您的
文档.getElementById
将替换为
第一节.current
(注意
.current
),最初设置为
null
,以避免在重新隐藏时发生卸载或缓存问题。

谢谢您的回答。你的建议很有道理。我已经逐渐重写了我的应用程序的工作方式,在这一点上,也许我应该支持按照你建议的方式完全重写。我会尽快尝试一下,看看我是否能达到我所需要的。我会重新考虑你的答案,一旦我这样做了,就把它标记为解决方案。再次感谢!美好的请记住使用
typeof窗口!='使用全局对象时未定义“
。您可以在我用来导航到这些部分的菜单中找到更多详细信息是全局的,因此我可以在另一个页面上,单击菜单中的项目名称,它应该更改路线、标识并转到该部分。您认为,我是否应该在HoC/context中设置一个状态,保存单击的菜单项的ID,然后在路线发生变化时对其进行操作?谢谢您的回答。你的建议很有道理。我已经逐渐重写了我的应用程序的工作方式,在这一点上,也许我应该支持按照你建议的方式完全重写。我会尽快尝试一下,看看我是否能达到我所需要的。我会重新考虑你的答案,一旦我这样做了,就把它标记为解决方案。再次感谢!美好的请记住使用
typeof窗口!='使用全局对象时未定义“