【问题标题】:how do you include w3school slideshow into reactJS component using hooks?你如何使用钩子将 w3school 幻灯片包含到 reactJS 组件中?
【发布时间】:2020-09-04 10:10:22
【问题描述】:

我有一些 javascript 代码需要迁移到 reactjs,我正在使用 react 钩子

但是当我包含 javascript 文件时出现错误

TypeError: 无法读取未定义的属性“样式”

我的组件代码

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>
    );
}

我的 app.js

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

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

export default App;

还有我的 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";
}

错误说它在第 63 行 (TypeError: Cannot read property 'style' of undefined)

  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 | }

【问题讨论】:

  • 似乎slides 是一个空数组,因为在 `slides[slideIndex - 1].style.display = "block"; 之前有这行 `slideIndex = slides.length;` ` 给出未定义的
  • 是的,这段代码在 html5 和 vanilla JS 中有效,但在 rsx 中找不到我的数组

标签: javascript reactjs


【解决方案1】:

它不应该工作,因为您在 React 代码之外执行 JavaScript 代码并且您希望它们一起工作。

您应该useState 存储您的vars 并在useEffect 中切换幻灯片。

这里或多或少是你应该瞄准的代码

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>
  );
}

如果您运行此代码,它应该可以工作并切换您的图像应该去的数字。

同样,这不是完美的代码,因为缺少拆分和 useCallbackuseRef 而不是文档查询,但它适用于您的情况,并为您提供了应该做什么的总体情况。

【讨论】:

  • 非常感谢。这段代码像 vanilla js 和 HTML 5 的版本一样工作得很好,通过这个例子,我可以尝试将我的 vanilla javascript 手风琴转换为 rsx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2012-03-27
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 2015-06-27
相关资源
最近更新 更多