简体   繁体   English

你如何使用钩子将 w3school 幻灯片包含到 reactJS 组件中?

[英]how do you include w3school slideshow into reactJS component using hooks?

I have some javascript code that I need to migrate to reactjs, I'm using react hooks我有一些需要迁移到 reactjs 的 javascript 代码,我正在使用 react 钩子

but when I include the javascript file an error appaers但是当我包含 javascript 文件时出现错误

TypeError: Cannot read property 'style' of undefined类型错误:无法读取未定义的属性“样式”

My component code我的组件代码

import React from "react";
import '../utils/slider';

export default function Slider()
{
    return(
        <div className="">
            <div className="slideshow-container" onmouseenter="pauseSlides()" onmouseleave="startSlides()">
                <div className="mySlides">
                    <img className ="img-responsive" src="image1.png" style="width:100%;"></img>
                </div>

                <div className="mySlides">
                    <img className ="img-responsive" src="image2.png" style="width:100%;"></img>
                </div>

                <div className="mySlides">
                    <img className ="img-responsive" src="image3.jpg" style="width:100%;"></img>
                </div>
            </div>

            <div style="text-align:center;">
                <span class="dot" onclick="currentSlide(0)"></span>
                <span class="dot" onclick="currentSlide(1)"></span>
                <span class="dot" onclick="currentSlide(2)"></span>
            </div>
        </div>
    );
}

My app.js我的 app.js

import React from 'react';
import Slider from "./components/Slider";

function App()
{
    return (
        <div className="App">
            <Slider />
        </div>
    );
}

export default App;

And my JavaScript code:还有我的 JavaScript 代码:

var slideIndex = 1;
var millis = 60000;

nextSlide();
var interval = setInterval(nextSlide, millis);

function resumeSlides()
{
    nextSlide();
}

function pauseSlides()
{
    clearInterval(interval);
}

function nextSlide()
{
    showSlide();
    slideIndex++;
}

function plusSlides(n)
{
    clearInterval(interval);
    slideIndex += n;
    nextSlide();
    interval = setInterval(nextSlide, millis);
}

function currentSlide(n)
{
    clearInterval(interval);
    slideIndex = n + 1;
    nextSlide();
    interval = setInterval(nextSlide, millis);
}

function showSlide()
{
    var i;
    var slides = document.getElementsByClassName("mySlides");
    var dots = document.getElementsByClassName("dot");
    
    for (i = 0; i < slides.length; i++)
        slides[i].style.display = "none";

    if (slideIndex > slides.length)
        slideIndex = 1;

    if (slideIndex < 1) 
        slideIndex = slides.length;

    for (i = 0; i < dots.length; i++) 
        dots[i].className = dots[i].className.replace(" active", "");

    slides[slideIndex - 1].style.display = "block";
    dots[slideIndex - 1].className += " active";
}

The error say it's on line 63 (TypeError: Cannot read property 'style' of undefined)错误说它在第 63 行(类型错误:无法读取未定义的属性“样式”)

  60 |      dots[i].className = dots[i].className.replace(" active", "");
  61 |  }
  62 | 
> 63 |  slides[slideIndex - 1].style.display = "block";
  64 |  dots[slideIndex - 1].className += " active";
  65 | }

Well it is not supposed to work since you execute JavaScript code outside your React code and you want them to work together.好吧,它不应该工作,因为您在 React 代码之外执行 JavaScript 代码并且您希望它们一起工作。

You should useState to store your vars and switch slides in useEffect .您应该useState来存储您的vars并在useEffect切换幻灯片。

Here is more or less the code you should aim to这里或多或少是你应该瞄准的代码

import React, { useEffect, useState } from "react";

export default function Slider() {
  // store your index and time in state
  const [slideIndex, setSlideIndex] = useState(1);
  const [millis, setMillis] = useState(2000);
  const [interval, setIntervalValue] = useState();

  // use effect to manage your interval
  useEffect(() => {
    startSlides();
    return pauseSlides;
  }, []);

  // change slides in effect
  useEffect(() => {
    showSlide();
  }, [slideIndex]);

  function nextSlide() {
    setSlideIndex((idx) => idx + 1); // use state set function
  }

  function currentSlide(idx) {
    setSlideIndex(idx);
  }

  function pauseSlides() {
    clearInterval(interval);
  }

  function startSlides() {
    nextSlide();
    const interval = setInterval(nextSlide, millis);
    setIntervalValue(interval);
  }

  function showSlide() {
    let slides = document.getElementsByClassName("mySlides");
    let dots = document.getElementsByClassName("dot");

    for (let i = 0; i < slides.length; i++) slides[i].style.display = "none";

    if (slideIndex > slides.length) {
      setSlideIndex(1);
    } else if (slideIndex < 1) {
      setSlideIndex(slides.length);
    } else {
      for (let i = 0; i < dots.length; i++)
        dots[i].className = dots[i].className.replace(" active", "");
      console.log(slideIndex);
      slides[slideIndex - 1].style.display = "block";
      dots[slideIndex - 1].className += " active";
    }
  }

  return (
    <div className="">
      <div
        className="slideshow-container"
        onMouseEnter={() => pauseSlides()}
        onMouseLeave={() => startSlides()}
      >
        <div className="mySlides">
          <img className="img-responsive" src="image1.png" alt="1"></img>
        </div>

        <div className="mySlides">
          <img className="img-responsive" src="image2.png" alt="2"></img>
        </div>

        <div className="mySlides">
          <img className="img-responsive" src="image3.jpg" alt="3"></img>
        </div>
      </div>

      <div>
        <span className="dot" onClick={() => currentSlide(0)}></span>
        <span className="dot" onClick={() => currentSlide(1)}></span>
        <span className="dot" onClick={() => currentSlide(2)}></span>
      </div>
    </div>
  );
}

If you run this code it should work and switch numbers where your images should go.如果您运行此代码,它应该可以工作并在您的图像应该去的地方切换数字。

Again, this is not perfect code, because a lack of split and useCallback and useRef instead of document query but it works for your case and gives you a overall picture of what should be done.同样,这不是完美的代码,因为缺少 split 和useCallbackuseRef而不是文档查询,但它适用于您的情况,并为您提供了应该做什么的总体情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM