Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays “单击时不更新图像数组的状态”事件_Arrays_Reactjs_React Hooks - Fatal编程技术网

Arrays “单击时不更新图像数组的状态”事件

Arrays “单击时不更新图像数组的状态”事件,arrays,reactjs,react-hooks,Arrays,Reactjs,React Hooks,我有一个图像网格填充了一个无头CMS的背景。当用户单击其中一个图像时,它们将被带到图像幻灯片中 我需要能够在网格中点击图像的索引处打开图像幻灯片 import React, { useState, useEffect, useRef } from "react"; import { css, jsx } from "@emotion/core"; import ImageSliderContent from "./ImageSliderConte

我有一个图像网格填充了一个无头CMS的背景。当用户单击其中一个图像时,它们将被带到图像幻灯片中

我需要能够在网格中点击图像的索引处打开图像幻灯片

import React, { useState, useEffect, useRef } from "react";
import { css, jsx } from "@emotion/core";
import ImageSliderContent from "./ImageSliderContent";
import styles from "./LocationsImageGallery.module.css";
import ImageGrid from "./ImageGrid";
import ImageSlide from "./ImageSlide";
import Arrow from "./Arrow";
import Dots from "./Dots";
import imageUrlBuilder from "@sanity/image-url";
import client from "../../client";

const builder = imageUrlBuilder(client);

const LocationsImageGallery = (props) => {
  const { caption, image } = props;

  const images = props.image;

  const [state, setState] = useState({
    translate: 0,
    transition: 0.45,
    activeSlide: 0,
  });

  const [showSlider, setShowSlider] = useState(false);
  const [showGrid, setShowGrid] = useState(true);

  const { translate, transition, activeSlide, _slides } = state;

  const size = useWindowSize();
  const transitionRef = useRef();

  function useWindowSize() {
    const isClient = typeof window === "object";

    function getSize() {
      return {
        width: isClient ? window.innerWidth : undefined,
      };
    }

    const [windowSize, setWindowSize] = useState(getSize);

    useEffect(() => {
      if (!isClient) {
        return false;
      }

      function handleResize() {
        setWindowSize(getSize());
      }

      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
    }, []);

    return windowSize;
  }

  const nextSlide = () => {
    if (activeSlide === images.length - 1) {
      return setState({
        ...state,
        translate: 0,
        activeSlide: 0,
      });
    }

    setState({
      ...state,
      activeSlide: activeSlide + 1,
      translate: (activeSlide + 1) * size.width,
    });
  };

  const prevSlide = () => {
    if (activeSlide === 0) {
      return setState({
        ...state,
        translate: (images.length - 1) * size.width,
        activeSlide: images.length - 1,
      });
    }

    setState({
      ...state,
      activeSlide: activeSlide - 1,
      translate: (activeSlide - 1) * size.width,
    });
  };

  const show = (index) => {
    setShowGrid(false);
    setShowSlider(true);
    setState({ activeSlide: index });
    console.log(activeSlide, index, state);
  };

  const hide = () => {
    setShowSlider(false);
    setShowGrid(true);
  };

  return (
    <div className={styles.root}>
      <div className={styles.header}>
        <a href="/locations">X</a>
      </div>
      {showGrid && (
        <div className={styles.imageGrid}>
          <div className={styles.imageGridContainer}>
            {images.map((image, index, caption) => (
              <div className={styles.imageContainer} onClick={() => show(index)}>
                <img
                  src={builder.image(image).auto("format").width(2000).url()}
                  className={styles.image}
                  alt={image.caption}
                  key={index}
                />
                <p className={styles.caption}>{image.caption}</p>
              </div>
            ))}
          </div>
        </div>
      )}

      {showSlider && (
        <div className={styles.imageGalleryContainer}>
          <div className={styles.imageSlider}>
            <ImageSliderContent
              translate={translate}
              transition={transition}
              width={size.width * images.length}
            >
              {images.map((image, index, caption) => (
                <>
                  <ImageSlide
                    key={image + index}
                    content={builder.image(image).auto("format").url()}
                  ></ImageSlide>
                </>
              ))}
            </ImageSliderContent>
            <Arrow direction="left" handleClick={prevSlide} />
            <Arrow direction="right" handleClick={nextSlide} />
          </div>
          <div className={styles.infoBar}>
            <p className={styles.infoCaption}>
              Locations / <span>{image.caption}</span>
            </p>
            <a href="" onClick={hide} className={styles.infoThumbnails}>
              Show Thumbnails
            </a>
          </div>
        </div>
      )}
    </div>
  );
};

export default LocationsImageGallery;

import React,{useState,useffect,useRef}来自“React”;
从“@emotion/core”导入{css,jsx};
从“/ImageSliderContent”导入ImageSliderContent;
从“/LocationsImageGallery.module.css”导入样式;
从“/ImageGrid”导入ImageGrid;
从“/ImageSlide”导入ImageSlide;
从“/Arrow”导入箭头;
从“/Dots”导入点;
从“@sanity/image url”导入imageUrlBuilder;
从“../../client”导入客户端;
const builder=imageUrlBuilder(客户端);
const LocationsImageGallery=(道具)=>{
const{caption,image}=props;
const images=props.image;
常量[状态,设置状态]=使用状态({
翻译:0,
过渡:0.45,
动态幻灯片:0,
});
常量[showSlider,setShowSlider]=useState(false);
const[showGrid,setShowGrid]=useState(true);
const{translate,transition,activeSlide,_slides}=state;
常量大小=UseWindowsSize();
const transitionRef=useRef();
函数useWindowsSize(){
const isClient=typeof window==“object”;
函数getSize(){
返回{
宽度:isClient?窗口。内部宽度:未定义,
};
}
const[windowSize,setWindowSize]=useState(getSize);
useffect(()=>{
如果(!isClient){
返回false;
}
函数handleResize(){
setWindowsSize(getSize());
}
addEventListener(“调整大小”,handleResize);
return()=>window.removeEventListener(“resize”,handleResize);
}, []);
返回窗口大小;
}
常量nextSlide=()=>{
如果(activeSlide==images.length-1){
返回设置状态({
……国家,
翻译:0,
动态幻灯片:0,
});
}
设定状态({
……国家,
activeSlide:activeSlide+1,
平移:(活动幻灯片+1)*size.width,
});
};
常数prevside=()=>{
如果(活动幻灯片===0){
返回设置状态({
……国家,
翻译:(images.length-1)*size.width,
activeSlide:images.length-1,
});
}
设定状态({
……国家,
activeSlide:activeSlide-1,
平移:(活动幻灯片-1)*size.width,
});
};
常量显示=(索引)=>{
设置显示网格(假);
设置显示滑块(真);
setState({activeSlide:index});
日志(activeSlide、索引、状态);
};
常量隐藏=()=>{
设置显示滑块(假);
设置显示网格(真);
};
返回(
{showGrid&&(
{images.map((图像、索引、标题)=>(
显示(索引)}>

{image.caption}

))} )} {showsslider&&( {images.map((图像、索引、标题)=>( ))} )} ); }; 导出默认位置SimageGallery;
此时,活动幻灯片和索引都被正确地传递给函数。但是,处于状态的activeSlide不会更新

如果我使用console.log(activeSlide、index、state),我会得到


0.5{translate:0,transition:0.45,activeSlide:0}

设置状态是异步的,如果要立即更改,请在设置状态中使用回调函数

setState({ activeSlide: index }, () => {});
这里有两个(甚至更多)主要的bug,一个是您记录了一个过时的状态,因为

第二个是
setState
useState
钩子,不合并状态,所以这样的代码:
setState({activeSlide:index})
实际上会覆盖其他状态值:
{translate,activeSlide,…}

通常,在这种情况下,您需要使用:


setState
是异步的,所以
console.log(activeSlide,index,state)
设置状态之后
不会一直是你认为应该读的代码!!!!请删除不重要的行以便于理解。谢谢!不幸的是,这将导致每次重新渲染和内部服务器错误问题是关于使用
useState
hook的功能组件
useState
没有可选的回调函数,因此这不起作用。哎呀,你说得对,我没有抓住要点。我没有读所有的代码,只是读了那一行,觉得setState就像我们以前的
this.setState()
。谢谢你,我仍然在努力学习钩子。我可以看出这是功能更新的正确方法,但是它似乎仍然没有更新activeSlide。因此,无论单击哪个索引,my console.log都会显示为activeSlide:0。您应该制作一个可复制的示例,这样的代码太长,无法理解,请阅读
const show = (index) => {
  setShowGrid(false);
  setShowSlider(true);
  setState((prev) => {
    console.log(prev);
    return { ...prev, activeSlide: index };
  });
};