gpt4 book ai didi

javascript - React : If a useState is updated, 如何同时不更新?

转载 作者:行者123 更新时间:2023-12-04 10:36:34 26 4
gpt4 key购买 nike

我有一个 react 代码

  • 设置一个 empty state
  • fills国家
  • 一旦这个状态被填满,它 renders一些图片
  • 此图像然后触发 onLoad事件
  • 这个 onLoad 事件然后调用一个 function那个reads初始state
  • 但是这个状态是empty

  • 怎么会这样?如果调用该函数,则表示状态不再为空

    钢笔 https://codesandbox.io/s/usestate-strange-things-9rydu

    编码

    import React, { useRef, useState, useEffect } from "react";
    import styled from "@emotion/styled";

    const useMyHook = (virtual_structure, setVirtual_structure) => {
    useEffect(() => {
    console.log("virtual_structure is updated!");
    console.log(virtual_structure);
    console.log("____virtual_structure is updated!");
    }, [virtual_structure]);

    const refs = useRef([]);

    const createStructure = () => {
    console.log("virtual_structure, is it empty?");
    console.log(virtual_structure);
    };

    useEffect(() => {
    createStructure();
    }, []);

    const assignRef = r =>
    r && (refs.current.includes(r) || refs.current.push(r));

    return [assignRef, createStructure];
    };

    export default function App() {
    const [virtual_structure, setVirtual_structure] = useState([]);

    const [assignRef, updateGrid] = useMyHook(
    virtual_structure,
    setVirtual_structure
    );

    useEffect(() => {
    const temp_structure = Array.from({ length: 4 }, () => ({
    height: 0,
    cells: []
    }));
    temp_structure[0].cells = Array.from({ length: 10 }, () => {
    const rand = Math.random();
    const r = rand > 0.1 ? parseInt(500 * rand) : parseInt(500 * 0.1);
    return {
    height: "",
    el: (
    <div ref={assignRef}>
    <Image
    alt=""
    onload={updateGrid}
    num=""
    src={`https://picsum.photos/200/${r}`}
    />
    </div>
    )
    };
    });

    setVirtual_structure(temp_structure);
    }, []);

    return (
    <Container>
    {virtual_structure.map((col, i) => (
    <div key={`col${i}`}>
    {col.cells && col.cells.map((cell, j) => <>{cell.el}</>)}
    </div>
    ))}
    </Container>
    );
    }

    const Image = ({ alt, onload, num, src }) => (
    <>
    <Label>{num}</Label>
    <Img src={src} alt={alt} onLoad={onload} />
    </>
    );

    const Img = styled.img`
    border: 1px solid #000;
    height: min-content;
    margin: 0;
    padding: 0;
    `;
    const Label = styled.div`
    position: absolute;
    `;

    const Container = styled.div`
    width: 100%;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    background: #ccc;
    align-content: center;

    div {
    flex: 1;

    div {
    color: #fff;
    font-weight: 700;
    font-size: 32px;
    margin: 4px;
    }
    }
    `;

    和 console.log
    virtual_structure is updated!
    index.js:27 Array(0)length: 0__proto__: Array(0)
    index.js:27 ____virtual_structure is updated!
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)
    index.js:27 virtual_structure is updated!
    index.js:27 Array(4)0: {height: 0, cells: Array(10)}1: {height: 0, cells: Array(0)}2: {height: 0, cells: Array(0)}3: {height: 0, cells: Array(0)}length: 4__proto__: Array(0)
    index.js:27 ____virtual_structure is updated!
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 Array(0)length: 0__proto__: Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 []length: 0__proto__: Array(0)
    index.js:27 virtual_structure, is it empty?
    index.js:27 []

    最佳答案

    这是由于 closures .

    您路过 updateGrid函数到每个 Image组件 一旦登上 :

    // useEffect closes its lexixal scope upon "updateGrid" 
    const [assignRef, updateGrid] = useMyHook(
    virtual_structure,
    setVirtual_structure
    );

    useEffect(() => {
    ...
    temp_structure[0].cells = Array.from({ length: 10 }, () => {
    return {
    el: (
    <div ref={assignRef}>
    // v Used inside the callback scope
    <Image onload={updateGrid} />
    </div>
    )
    };
    });

    setVirtual_structure(temp_structure);
    }, []);

    但是, virtual_structure 的值在 updateGrid (即您重命名的 createStructure)实际上总是等于 []useEffect 的词法范围内打回来。虽然 createStructure对渲染进行更新, 它从未通过Image组件 与预期值 .
    const createStructure = () => {
    console.log('virtual_structure, is it empty?');
    console.log(virtual_structure); // always virtual_structure=[]
    };

    Side note: never ignore lint warnings, although you might know what you are doing, it may lead to unexpected bugs.

    关于javascript - React : If a useState is updated, 如何同时不更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60154031/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com