如何使用 React Hook 在 React 组件中引用和加载 Javascript 文件
Posted
技术标签:
【中文标题】如何使用 React Hook 在 React 组件中引用和加载 Javascript 文件【英文标题】:How to reference and load Javascript file(s) inside a React Component using a React Hook 【发布时间】:2020-11-19 13:30:38 【问题描述】:我是 React 的新手,我正在尝试使用一个名为 useEffect 的 React Hook 来在 javascript 中加载一个小脚本。 javascript 代码正在获取完整的当年,我试图在我网站的 FooterBottom 组件中调用它。我正在使用 tailwindcss 来制作这个 React 应用程序的样式。我见过一些使用这种方法的解决方案,例如:Adding script tag to React/JSX 和 How 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 © MyComponent(), All Rights Reserved.</p>
<div className="footer_copyright">
Designed by <a href="https://tailwindcss.com/">tailwindcss.com</a>
</div>
</div>
</div>
</div>
);
【问题讨论】:
【参考方案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 © 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 © 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 的工作原理来看,我认为这个钩子只有在应用程序呈现而不是整个网站本身时才有用。以上是关于如何使用 React Hook 在 React 组件中引用和加载 Javascript 文件的主要内容,如果未能解决你的问题,请参考以下文章
react的hook踩坑,useState的set方法不生效问题。
如何使用 React Hook 在 React 组件中引用和加载 Javascript 文件
如何使用 react-hook-form 有条件地禁用提交按钮?