首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试使用useRef对run /Remix/Prisma中生成的项运行函数

尝试使用useRef对run /Remix/Prisma中生成的项运行函数
EN

Stack Overflow用户
提问于 2022-01-27 12:54:54
回答 2查看 893关注 0票数 0

我已经看过多个useRef/useEffect指令,但我似乎无法在这里工作。

这里的代码工作流程是:混合/反应,从数据库获取数据,显示数据,将数据转换为可以更新的代码。

如果有人能指出他们在这段代码中看到的任何明显错误,说明为什么useEffect钩子没有启动,或者为什么useRef钩子永远找不到<ul>中的{listRef},我很想知道。

代码语言:javascript
复制
import { Links, redirect, useLoaderData, Outlet } from 'remix'
import { db } from '~/utils/db.server'
import { getUser } from '~/utils/session.server'
import { ReactSortable } from "react-sortablejs"
import { useState, useRef, useEffect } from 'react'
import tickerStylesUrl from '~/styles/tickerDisplay.css'

export const links = () => [{ rel: 'stylesheet', href: tickerStylesUrl }]

export const loader = async ({ request, params }) => {
  
  const user = await getUser(request)
  const ticker = await db.ticker.findUnique({
    where: { id: params.tickerId },
    include: {
      headlines: true,
    },
  })
  if (!ticker) throw new Error('Ticker not found')

  const data = { ticker, user }
  return data
}

export const action = async ({ request, params }) => {

}
// The ticker function displays the items without styling, so it finds the database perfectly and can get the data
function displayTicker() {
  const { ticker, user } = useLoaderData()

  const headlines = ticker.headlines
  const tickerParentStyle = {
    width: "1920px",
    height: "1080px",
    position: "relative",
    backgroundColor: "black"
  }
  const tickerStyle = {
    position: "absolute",
    padding: "0",
    bottom: "0",
    color: `${ticker.fontColor}`,
    backgroundColor: `${ticker.backgroundColor}`,
    fontFamily: `${ticker.font}`,
    fontSize: "2em",
  }
  const tickerHeadlineStyle = {
    margin: "auto",
    height: "50%",
  }
  console.log("Headlines: " + headlines)
  // So begins the found ticker code I had hoped to integrate
  // Source: https://www.w3docs.com/tools/code-editor/2123
  function scrollTicker() {

    const marquee = listRef.current.querySelectorAll('.tickerHeadlines');
    let speed = 4;
    let lastScrollPos = 0;
    let timer;
    marquee.forEach(function (el) {
      const container = el.querySelector('.headlineItem');
      const content = el.querySelector('.headlineItem > *');
      //Get total width
      const elWidth = content.offsetWidth;
      //Duplicate content
      let clone = content.cloneNode(true);
      container.appendChild(clone);
      let progress = 1;
      function loop() {
        progress = progress - speed;
        if (progress <= elWidth * -1) {
          progress = 0;
        }
        container.style.transform = 'translateX(' + progress + 'px)';
        container.style.transform += 'skewX(' + speed * 0.4 + 'deg)';
        window.requestAnimationFrame(loop);
      }
      loop();
    });
    window.addEventListener('scroll', function () {
      const maxScrollValue = 12;
      const newScrollPos = window.scrollY;
      let scrollValue = newScrollPos - lastScrollPos;
      if (scrollValue > maxScrollValue) scrollValue = maxScrollValue;
      else if (scrollValue < -maxScrollValue) scrollValue = -maxScrollValue;
      speed = scrollValue;
      clearTimeout(timer);
      timer = setTimeout(handleSpeedClear, 10);
    });
    function handleSpeedClear() {
      speed = 4;
    }
  }

  const listRef = useRef()
  console.log("listRef: " + JSON.stringify(listRef))
  // This console appears everytime, but is always empty, presumably because DOM has just rendered

  useEffect(() => {
    console.log("useEffect fired")
    // This console NEVER fires, sadly. I thought this would happen ONCE rendered
  }, [listRef]);

  return (
    <>
      <Links />
      <div style={tickerParentStyle}>
        <div style={tickerStyle}>
          <div key={ticker.id} style={tickerHeadlineStyle} class="tickerWrapper">
// HERE IS THE TARGET UL
            <ul className="tickerHeadlines" ref={listRef} style={{ margin: "10px 0 10px 0" }} >
              {/* Hoping to map through the ticker items here, and have them displayed in a list, which would then be manipulated by the useRef/useEffect hook */}
              {headlines.map((headline) => (
                <>
                  <li class="headlineItem" key={headline.id}>
                    <span>
                      {headline.content} {ticker.seperator}
                    </span>
                  </li>
                </>
              ))}
              {scrollTicker()}
            </ul>
          </div>
        </div>
      </div>
    </>
  )
}

export default displayTicker

一如既往,任何帮助都是值得感激的。

EN

回答 2

Stack Overflow用户

发布于 2022-01-29 19:11:13

useRef是一个用于访问DOM元素的钩子,直接在React应用程序中操作DOM破坏了声明式编程的全部要点。不建议直接使用任何DOM对象和方法(如document )来操作dom。进入useEffect钩子时,useEffect钩子将根据依赖数组中提供的内容有条件地运行,如果没有,则该钩子在组件完成挂载后只运行一次。因此,您应该注意需要传递给useEffect依赖数组的内容。考虑到您的情况,当您传递listRef时,useEffect只在对象中发生更改而不是它的属性发生更改时才运行,因为对象是非原始的,因此该属性中的任何更改都不会被视为对象中的更改,而它仅仅是一个不会导致重呈现的对象属性突变。为了避免这种情况,您应该确信,正如您前面提到的,您希望在数据呈现后立即运行它,您可以在依赖项数组中使用headlines。将依赖项数组更改为包含headlines

代码语言:javascript
复制
 useEffect(() => {
    console.log("useEffect fired")
    // This console NEVER fires, sadly. I thought this would happen ONCE rendered
  }, [headlines]);

或者,您也可以将其保留为空,使其在组件挂载后只运行一次。

代码语言:javascript
复制
useEffect(() => {
    console.log("useEffect fired")
    // This console NEVER fires, sadly. I thought this would happen ONCE rendered
  }, []);

请注意,每次headlines发生更改时,前者都会运行一次,而后者无论发生什么变化都只运行一次。因此,根据您的用例,您可能希望选择最适合您的需求。

票数 2
EN

Stack Overflow用户

发布于 2022-02-02 20:44:30

有几件事情可以让代码变得更好:

  1. 使用“null”值

启动ref

  1. 在useEffect Hook.

中调用“scrollTicker”函数

当组件退出时,

  1. 总是删除侦听器。请按照https://reactjs.org/docs/hooks-reference.html#useeffect获取更多详细信息,

  1. 您可以像这样使用useEffect钩子:

useEffect(() ) => { //在这里使用你的参考资料。返回() => { //删除链接器

};};

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70878916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档