【问题标题】:How to reference and load Javascript file(s) inside a React Component using a React Hook如何使用 React Hook 在 React 组件中引用和加载 Javascript 文件
【发布时间】:2020-11-19 13:30:38
【问题描述】:

我是 React 的新手,我正在尝试使用一个名为 useEffectReact Hook 来在 Javascript 中加载一个小脚本。 javascript 代码正在获取完整的当年,我试图在我网站的 FooterBottom 组件中调用它。我正在使用 tailwindcss 来制作这个 React 应用程序的样式。我见过一些使用这种方法的解决方案,例如:Adding script tag to React/JSXHow do i use external script that i add to react JS?

我避免使用 componentDidMount(),因为我想学习如何使用 React Hooks 来使用它。非常感谢任何帮助。

Javascript: fullYear.js

var d = new Date();
var n = d.getFullYear();

document.write(d);

React Hook: useScript.js

import { useEffect } from 'react'

const useScript = function (file) {
  useEffect(() => {
    const script = document.createElement('script');

    script.src = file;
    script.type = 'type/javascript';
    script.async = true;
    script.onload = () => this.scriptLoaded();

    document.body.appendChild(script);

  }, [file]);
};
export default useScript;

React 组件: FooterBottom.js

import React from 'react'
import useScript from './hooks/useScript.js'

const mystyle = {
  visibility: 'visible'
};

const MyComponent = props => {
  useScript('../assets/fullYear.js')
}

export default function FooterBottom() {
  return (
    <div className="footer-bottom">
      <div className="container items-center mx-auto ">
        <div style={mystyle} className="bg-gray-800 text-center text-white wow zoomIn">
          <p>Copyright &copy; {MyComponent()}, All Rights Reserved.</p>
          <div className="footer_copyright">
            Designed by <a href="https://tailwindcss.com/">tailwindcss.com</a>
          </div>
        </div>
      </div>
    </div>
  );
}

【问题讨论】:

    标签: javascript reactjs components react-hooks jsx


    【解决方案1】:

    您似乎在使用此脚本只是为了向您提供最近一年的版权。与尝试做你目前正在做的事情相比,使用以下内容要干净得多。

    import React from 'react'
    
    export default function FooterBottom() {
     const currentYear = new Date().getFullYear();
    
     return (
       <div className="footer-bottom">
         <div className="container items-center mx-auto ">
           <div style={mystyle} className="bg-gray-800 text-center text-white wow zoomIn">
             <p>Copyright &copy; {currentYear}, All Rights Reserved.</p>
             <div className="footer_copyright">
               Designed by <a href="https://tailwindcss.com/">tailwindcss.com</a>
             </div>
           </div>
         </div>
       </div>
     );
    }
    

    现在我了解到您正在尝试学习如何使用钩子,所以我会稍微解释一下。

    默认情况下,useEffect 中的任何内容都会在组件刷新时随时运行(称为重新渲染)。组件通常只会在自身或父状态发生变化时重新渲染。

    useEffect 总是在第一次加载组件时运行一次,但我们也可以使用作为参数传递的数组来控制使 useEffect 触发的原因。例如,传递一个空数组 [] 将使 useEffect 在第一次渲染时运行一次。 在您的情况下,传递 [file] 意味着 useEffect 块内的代码将file 发生更改时执行

    看看下面的代码。您会注意到我有 2 个状态正在更新。左键将更新计数,右键将更新 countTwo。您还会注意到有多个 useEffect 块。可以这样做来控制更新时要运行的内容。

    如你所见,第一次 useEffect 只会将代码块第一次 渲染 App 组件,就是这样。

    每次重新渲染 App 时都会执行第二个 useEffect。当按下任何按钮时,应用会重新渲染,因为它会更新 count 或 countTwo。

    第三个 useEffect 将在 App 重新渲染时执行,但仅在 countTwo 更改时执行。

    所以即使你按下左键,第三个 useEffect 也不会运行。只有第二个。但是如果你按下右键,第三个 useEffect 会在第二个 useEffect 之外运行。

    import React, { useEffect } from "react";
    import "./styles.css";
    
    export default function App() {
      const [count, setCount] = React.useState(0);
      const [countTwo, setCountTwo] = React.useState(0);
    
      // THIS WILL ONLY RUN ON FIRST LOAD
      useEffect(()=> {
        console.log("I will only run on first component load!")
      },[])
    
      // THIS WILL RUN ANYTIME THE APP RE-RENDERS
      useEffect(() => {
        console.log("App was re-rendered, and count was updated");
      });
    
      // THIS WILL ONLY RUN WHEN THE APP RE-RENDERS AND countTWO
      // IS UPDATED
      useEffect(() => {
        console.log("App was re-rendered, and countTwo was updated");
      }, [countTwo]);
    
      return (
        <div className="App">
          <button onClick={() => setCount(count + 1)}>Count: {count}</button>
    
          <button onClick={() => setCountTwo(countTwo + 1)}>
            Count2: {countTwo}
          </button>
        </div>
      );
    }
    
    

    https://codesandbox.io/s/distracted-chatterjee-xznxd?file=/src/App.js

    这样想,useEffect中运行的代码,就是组件刷新带来的‘效果’。我们可以控制哪些变化会触发效果,以及当不同的变量/状态更新时会发生什么不同。

    最后,为什么你的代码不工作也是因为这不是你使用外部 javascript 文件的方式。

    您需要在外部文件中创建一个函数,然后将其导出。然后你将它导入到你的 react 项目中。

    示例如下:

    Javascript:fullYear.js

    export default function getYear() {
      return new Date().getFullYear();
    }
    

    React 组件:FooterBottom.js

    import React from 'react'
    import getYear from './fullYear'
    
    export default function FooterBottom() {
      return (
        <div className="footer-bottom">
          <div className="container items-center mx-auto ">
            <div style={mystyle} className="bg-gray-800 text-center text-white wow zoomIn">
              <p>Copyright &copy; {getYear()}, All Rights Reserved.</p>
              <div className="footer_copyright">
                Designed by <a href="https://tailwindcss.com/">tailwindcss.com</a>
              </div>
            </div>
          </div>
        </div>
      );
    }
    

    希望这是对外部文件如何工作以及 useEffect 如何工作的一个很好的解释。

    【讨论】:

    • 我明白了。我试图做的是将我的 javascript 代码“注入”到组件中,认为这可能是保持我的代码更清洁的唯一方法,同时在运行时更有效地加载。因此,如果我想将更多 js 文件加载到我的组件中,我会使用 useEffect 这样做,因为我必须卸载它们以防止网站呈现时进一步延迟。这就是为什么我使用了一个简单的最近一年的 js 代码。从 useEffect 的工作原理来看,我认为这个钩子只有在应用程序呈现而不是整个网站本身时才有用。
    猜你喜欢
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    • 2022-12-21
    • 1970-01-01
    相关资源
    最近更新 更多