在 DOM 在 reactjs 中呈现后,我想 运行 一个 JS 文件

I want to run a JS file after the DOM is rendered in reactjs

我正在将 HTML 主题转换为 Reactjs,我很难尝试嵌入该模板的外部 Javascript 文件。我尝试使用 useEffect 将脚本附加到 body 但没有成功。我认为我的问题是 Javascript 文件中的函数在 DOM 渲染之前执行,无论哪种方式我的模板都无法正确渲染为 HTML.

该外部脚本具有以下类型的内容:

function(a) {
  var b = window.ABC|| {};
  b = function() {
    function c(c, d) {
      var f, e = this;
      e.defaults = {
        .....
    }
    var b = 0;
    return c
  }(),...

我已经搜索了几天但没有结果

已编辑:

SingleProduct.js 我希望产品滑块中的图像有效

import React, { useEffect, useLayoutEffect } from 'react';
import RelatedProduct from '../Partials/RelatedProduct';

const SingleProduct = () => {
  useLayoutEffect(() => {
    document.body.style = 'background: #fff'
  }, [])

  useEffect(() => {
    const script = document.createElement('script')
    script.src = '/assets/js/slick-slider.js' // path of the plugin called Slick Slider
    script.async = true // false not work too
    document.body.append(script) // the element <script> is appended but no work
  }, [])

  return (
    <>
    ...

The element is appended but no work

本应在Slider中的图片仍然无法正常显示,(它们只是按顺序显示)

import '../hooks/slick-slider.min';

还有一件事:外部 js 文件插件可以 运行 网站第一次出现时,但是当我使用 react-router 切换到另一条路线并返回时,它无法正确呈现,很难解释一下,但我敢肯定的是,有很多人像我一样没有解决这个问题。

我已经搜索并找到了与类型 IIFE 函数相关的答案,但我认为一定有解决方法?

我要嵌入的脚本:https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js

我知道这个插件已经在 NPM 上了,但我想尝试以这种方式将它嵌入我的网站并解决我的问题。

最简单的方法是将您的脚本直接添加到您的 html-head 标签(或其他地方):

<script src="https://code.jquery.com/jquery-3.6.0.min.js" id="external-js"></script>
<script src="https://kenwheeler.github.io/slick/slick/slick.js" id="external-js"></script>

这样,你的组件基本上可以简化为:

import React, { useEffect } from "react";
import ReactDOM from "react-dom";

const App = () => {
  useEffect(
    () => {
      const sliderComponent = jQuery(".img-slider");

      sliderComponent.slick();
    },
    [/* run once or add image source dependencies */]
  );

  return (
    <div className="img-slider" style={{ width: 300 }}>
      <img src="https://picsum.photos/200" />
      <img src="https://picsum.photos/200" />
      <img src="https://picsum.photos/200" />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("container"));

另一种方法是按照您的建议动态添加脚本。不幸的是,这需要您编写更多代码,正如您所需要的那样,请确保在您调用 sliderComponent.slick() 时加载脚本。在我的脑海中,这可能看起来像下面这样,大量借用 。

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";



const scripts = [
  "https://code.jquery.com/jquery-3.6.0.min.js",
  "https://kenwheeler.github.io/slick/slick/slick.js"
];

// borrowed from Jaykesh Patel, but modified to use Promises
// 
function loadScript( url ) {

  return new Promise((resolve, reject) => {
    var script = document.createElement( "script" )
    script.type = "text/javascript";
    if(script.readyState) {  // only required for IE <9
      script.onreadystatechange = function() {
        if ( script.readyState === "loaded" || script.readyState === "complete" ) {
          script.onreadystatechange = null;
          resolve();
        }
      };
    } else {  //Others
      script.onload = function() {
        resolve();
      };
    }
  
    script.src = url;
    document.getElementsByTagName( "head" )[0].appendChild( script );
  })


}


const useScripts = () => {  
  const [isLoaded, setLoaded] = useState(false);

  useEffect(() => {    
    Promise
    .all(scripts.map(script => loadScript(script)))
    .then(() => setLoaded(true));
  }, []);


  return isLoaded;
}


const App = () => {

  const isLoaded = useScripts();

  useEffect(
    () => {

      if(!isLoaded){
        return;
      }

      const sliderComponent = jQuery(".img-slider");

      sliderComponent.slick();
    },
    [
      isLoaded      
    ]
  );

  return (
    <div className="img-slider" style={{ width: 300 }}>
      <img src="https://picsum.photos/200" />
      <img src="https://picsum.photos/200" />
      <img src="https://picsum.photos/200" />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("container"));