[英]What is preventing this function from executing the hooks inside of it? What about react mechanics makes this impossible?
I'm trying to execute a function that executes other functions.我正在尝试执行执行其他功能的 function。 The function itself executes but the functions inside of it do not.
function 本身执行,但其内部的功能不执行。 I thought I had a good grasp on React mechanics and it's lifecycle but I guess not.
我以为我对 React 机制和它的生命周期有很好的掌握,但我想不是。 I do not understand why react is acting this way.
我不明白为什么 react 会这样。 Hoping for guidance/an explanation on the react component lifecycle and what about it that prevents this particular code from working.
希望获得有关反应组件生命周期的指导/解释,以及阻止此特定代码工作的原因。
getInfo.jsx获取信息.jsx
import { useState, useEffect } from "react";
export const useGetCompletionData = () => {
const [sandIsActive, setSandActive] = useState(false);
const [dragonIsActive, setDragonActive] = useState(false);
const [splinterIsActive, setSplinterActive] = useState(false);
const [tigerIsActive, setTigerActive] = useState(false);
const [reptileIsActive, setReptileActive] = useState(false);
const [jungleIsActive, setJungleActive] = useState(false);
const [totalCamo, setTotalCamo] = useState(0);
const [goldIsActive, setGoldActive] = useState(false);
const handleSandClick = (event) => {
// 👇️ toggle isActive state on click
setSandActive((current) => !current);
if (sandIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleDragonClick = (event) => {
// 👇️ toggle isActive state on click
setDragonActive((current) => !current);
if (dragonIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleSplinterClick = (event) => {
// 👇️ toggle isActive state on click
setSplinterActive((current) => !current);
if (splinterIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleTigerClick = (event) => {
// 👇️ toggle isActive state on click
setTigerActive((current) => !current);
if (tigerIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleReptileClick = (event) => {
// 👇️ toggle isActive state on click
setReptileActive((current) => !current);
if (reptileIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleJungleClick = (event) => {
// 👇️ toggle isActive state on click
setJungleActive((current) => !current);
if (jungleIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const setAllCamos = (event) => {
console.log("set all camos start");
handleSandClick();
handleDragonClick();
handleSplinterClick();
handleTigerClick();
handleJungleClick();
console.log("set all camos finished");
};
return {
goldIsActive,
setGoldActive,
totalCamo,
setTotalCamo,
sandIsActive,
handleSandClick,
handleDragonClick,
dragonIsActive,
splinterIsActive,
handleSplinterClick,
tigerIsActive,
handleTigerClick,
handleReptileClick,
reptileIsActive,
jungleIsActive,
handleJungleClick,
setAllCamos,
};
};
AR_list.jsx AR_list.jsx
import React from "react";
import CamoList from "../Completion/CamoList";
import { useState } from "react";
import { useGetCompletionData } from "../../hooks/getInfo";
export default function AR_LIST() {
const [damascusPercent, setDamascusPercent] = useState(0);
let { setAllCamos } = useGetCompletionData();
return (
<>
<h1>Assault Rifle</h1>
<div className="gun-grid">
<div>
<h1>ASM10</h1>
<img
src="https://i.imgur.com/4rk88oj.jpg"
alt="ASM10"
onDoubleClick={setAllCamos}
/>
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>AK-47</h1>
<img src="https://i.imgur.com/tiwEg6m.jpg" alt="AK47" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>M16</h1>
<img src="https://i.imgur.com/xGbpnJb.jpg" alt="M16" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>M4</h1>
<img src="https://i.imgur.com/LP0kr6K.jpg" alt="M4" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>BK57</h1>
<img src="https://i.imgur.com/mUp4KH7.jpg" alt="BK57" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>LK24</h1>
<img src="https://i.imgur.com/3iNpSfh.jpeg" alt="LK24" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>AK117</h1>
<img
src="https://zilliongamer.com/uploads/codm/skins/assault/ak117/ak117-munitions-cod-mobile.jpg"
alt="AK117"
/>
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>M13</h1>
<img
src="https://zilliongamer.com/uploads/codm/weapons/ar/m13/m13-cod-mobile.jpg"
alt="M13"
/>
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>Kilo 141</h1>
<img
src="https://zilliongamer.com/uploads/codm/weapons/ar/kilo-141/kilo-141-call-of-duty-mobile.jpg"
alt="Kilo 141"
/>
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>KN-44</h1>
<img src="https://i.imgur.com/OzlDWlk.jpg" alt="KN-44" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>Man-O-War</h1>
<img src="https://i.imgur.com/Y8AYudI.jpg" alt="Man-O-War" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>CR-56 AMAX</h1>
<img src="https://i.imgur.com/3ZWIfZA.jpg" alt="CR-56 AMAX" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>AS VAL</h1>
<img src="https://i.imgur.com/6mzUd8F.jpg" alt="AS VAL" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>Swordfish</h1>
<img src="https://i.imgur.com/pI8GQ6G.jpg" alt="Swordfish" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>HVK-30</h1>
<img src="https://i.imgur.com/pCJHS2J.jpg" alt="HVK-30" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>Peacekeeper MK2</h1>
<img src="https://i.imgur.com/joXdWda.jpg" alt="Peacekeeper MK2" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>FR .556</h1>
<img src="https://i.imgur.com/zn8pshJ.jpg" alt="FR .556" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>Oden</h1>
<img src="https://i.imgur.com/Iupg5eL.jpg" alt="Oden" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>ICR-1</h1>
<img src="https://i.imgur.com/aJNh1Kb.jpg" alt="ICR-1" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>HBRa3</h1>
<img src="https://i.imgur.com/0Imj29v.jpg" alt="HBRa3" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
<div>
<h1>DR-H</h1>
<img src="https://i.imgur.com/QE8KvoQ.jpg" alt="DR-H" />
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
</div>
</>
);
}
CamoList.jsx迷彩列表.jsx
import { useState, useEffect, useContext } from "react";
import { FaCheck } from "react-icons/fa";
import React from "react";
import { useGetCompletionData } from "../../hooks/getInfo";
import { damascusProgress } from "../../damascusContext";
export default function CamoList({ damascusPercent, setDamascusPercent }) {
const {
goldIsActive,
setGoldActive,
totalCamo,
setTotalCamo,
sandIsActive,
handleSandClick,
handleDragonClick,
dragonIsActive,
splinterIsActive,
handleSplinterClick,
tigerIsActive,
handleTigerClick,
handleReptileClick,
reptileIsActive,
jungleIsActive,
handleJungleClick,
} = useGetCompletionData();
let { setCount } = useContext(damascusProgress);
useEffect(() => {
if (totalCamo === 6) {
setGoldActive((current) => !current);
setDamascusPercent((prev) => prev + 1);
setTotalCamo((prev) => prev + 1);
setCount((prev) => prev + 4.8);
updateFill();
}
function updateFill() {
let number = (damascusPercent / 20) * 100;
document.documentElement.style.setProperty(
"--circle-radius",
`${number}deg`
);
}
updateFill();
}, [totalCamo]);
return (
<div className="collection">
<p>{damascusPercent}</p>
<div
id="sand"
className={sandIsActive ? "active" : ""}
onClick={handleSandClick}
>
<div className={sandIsActive ? "tooltip-hidden" : "tooltip"}>
<span className="tooltiptext">Kill 600 enemies</span>
</div>
<FaCheck className={sandIsActive ? "checkmarkSand" : "nocheckmark"} />
</div>
<div
id="dragon"
className={dragonIsActive ? "active" : ""}
onClick={handleDragonClick}
>
<div className={dragonIsActive ? "tooltip-hidden" : "tooltip"}>
<span className="tooltiptext">Kill 50 enemies with hip fire</span>
</div>
<FaCheck
className={dragonIsActive ? "checkmarkDragon" : "nocheckmark"}
/>
</div>
<div
id="splinter"
className={splinterIsActive ? "active" : ""}
onClick={handleSplinterClick}
>
<div className={splinterIsActive ? "tooltip-hidden" : "tooltip"}>
<span className="tooltiptext">Kill 80 enemies at long distance</span>
</div>
<FaCheck
className={splinterIsActive ? "checkmarkSplinter" : "nocheckmark"}
/>
</div>
<div
id="tiger"
className={tigerIsActive ? "active" : ""}
onClick={handleTigerClick}
>
<div className={tigerIsActive ? "tooltip-hidden" : "tooltip"}>
<span className="tooltiptext">
Kill 125 enemies with 5 attachments equipped
</span>
</div>
<FaCheck className={tigerIsActive ? "checkmarkTiger" : "nocheckmark"} />
</div>
<div
id="jungle"
className={jungleIsActive ? "active" : ""}
onClick={handleJungleClick}
>
<div className={jungleIsActive ? "tooltip-hidden" : "tooltip"}>
<span className="tooltiptext">Kill 100 enemies with head shots</span>
</div>
<FaCheck
className={jungleIsActive ? "checkmarkJungle" : "nocheckmark"}
/>
</div>
<div
id="reptile"
className={reptileIsActive ? "active" : ""}
onClick={handleReptileClick}
>
<div className={reptileIsActive ? "tooltip-hidden" : "tooltip"}>
<span className="tooltiptext">
Kill 80 enemies with no attachments equipped
</span>
</div>
<FaCheck
className={reptileIsActive ? "checkmarkReptile" : "nocheckmark"}
/>
</div>
<div id="gold" className={goldIsActive ? "gold-active" : ""}>
<div className={goldIsActive ? "tooltip-hidden" : "tooltip"}>
<span className="tooltiptext">Unlock all previous camos</span>
</div>
<FaCheck className={goldIsActive ? "checkmarkGold" : "nocheckmark"} />
</div>
<div id="platinum"></div>
<div id="demas"></div>
</div>
);
}
Link directly to the function in question on CodeSandbox:在 CodeSandbox 上直接链接到有问题的 function:
https://codesandbox.io/s/practical-gates-rr81j0?file=/src/hooks/getInfo.jsx:2112-2357 https://codesandbox.io/s/practical-gates-rr81j0?file=/src/hooks/getInfo.jsx:2112-2357
Context: I'm trying to make it so double clicking on the picture of the gun sets the camo boxes underneath it to "active".背景:我试图让它双击枪的图片将其下方的迷彩框设置为“活动”。 Each hook function for each box works individually, but when called together in a function nothing happens.
每个盒子的每个钩子 function 单独工作,但是当在 function 中一起调用时,什么也没有发生。 Both console.log()'s execute, but not the functions in between them.
两个 console.log() 都执行,但不是它们之间的函数。 I was under the impression that calling each "handle${Camo}Click" function in a separate function would work fine, but it doesn't.
我的印象是,在单独的 function 中调用每个“handle${Camo}Click”function 可以正常工作,但事实并非如此。 I don't know what to search to start figuring out the mechanics of why this happening.
我不知道要搜索什么才能开始弄清楚为什么会发生这种情况的机制。 If anyone could point me in the right direction that would be very much appreciated.
如果有人能指出我正确的方向,那将不胜感激。
The issue is that you've defined a useGetCompletionData
hook with its own state, but use several instances of the hook so each instance has and maintains its own state independently.问题是您已经使用自己的 state 定义了一个
useGetCompletionData
挂钩,但使用了多个挂钩实例,因此每个实例都拥有并独立维护自己的 state。
The setAllCamos
callback the the ASM10 image is calling is from a different instance of the useGetCompletionData
hook that it's related CamoList
component is using. ASM10 图像正在调用的
setAllCamos
回调来自与其相关的CamoList
组件正在使用的useGetCompletionData
挂钩的不同实例。 In other words, when the image is double-clicked it's updating state the Camolist
doesn't have access to.换句话说,当双击图像时,它正在更新
Camolist
无法访问的 state。
I suggest creating a CompletionDataProvider
component to wrap individual sets of images and CamoList
components so they can share and reference the same state.我建议创建一个
CompletionDataProvider
组件来包装各个图像集和CamoList
组件,以便它们可以共享和引用相同的 state。
Example:例子:
getInfo.jsx获取信息.jsx
import { createContext, useContext, useState } from "react";
export const CompletionData = createContext({
goldIsActive: false,
setGoldActive: () => {},
totalCamo: 0,
setTotalCamo: () => {},
sandIsActive: false,
handleSandClick: () => {},
handleDragonClick: () => {},
dragonIsActive: false,
splinterIsActive: false,
handleSplinterClick: () => {},
tigerIsActive: false,
handleTigerClick: () => {},
handleReptileClick: () => {},
reptileIsActive: false,
jungleIsActive: false,
handleJungleClick: () => {},
setAllCamos: () => {},
});
const CompletionDataProvider = ({ children }) => {
const [sandIsActive, setSandActive] = useState(false);
const [dragonIsActive, setDragonActive] = useState(false);
const [splinterIsActive, setSplinterActive] = useState(false);
const [tigerIsActive, setTigerActive] = useState(false);
const [reptileIsActive, setReptileActive] = useState(false);
const [jungleIsActive, setJungleActive] = useState(false);
const [totalCamo, setTotalCamo] = useState(0);
const [goldIsActive, setGoldActive] = useState(false);
const handleSandClick = () => {
// 👇️ toggle isActive state on click
setSandActive((current) => !current);
if (sandIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleDragonClick = () => {
// 👇️ toggle isActive state on click
setDragonActive((current) => !current);
if (dragonIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleSplinterClick = () => {
// 👇️ toggle isActive state on click
setSplinterActive((current) => !current);
if (splinterIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleTigerClick = () => {
// 👇️ toggle isActive state on click
setTigerActive((current) => !current);
if (tigerIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleReptileClick = () => {
// 👇️ toggle isActive state on click
setReptileActive((current) => !current);
if (reptileIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const handleJungleClick = () => {
// 👇️ toggle isActive state on click
setJungleActive((current) => !current);
if (jungleIsActive) {
setTotalCamo((prev) => prev - 1);
} else {
setTotalCamo((prev) => prev + 1);
}
};
const setAllCamos = () => {
handleSandClick();
handleDragonClick();
handleSplinterClick();
handleTigerClick();
handleJungleClick();
};
const value = {
goldIsActive,
setGoldActive,
totalCamo,
setTotalCamo,
sandIsActive,
handleSandClick,
handleDragonClick,
dragonIsActive,
splinterIsActive,
handleSplinterClick,
tigerIsActive,
handleTigerClick,
handleReptileClick,
reptileIsActive,
jungleIsActive,
handleJungleClick,
setAllCamos
};
return (
<CompletionData.Provider {...{ value }}>
{children}
</CompletionData.Provider>
);
};
export const useGetCompletionData = () => useContext(CompletionData);
export default CompletionDataProvider;
AR_list.jsx AR_list.jsx
Wrap the image and CamoList
component "pairs" in the imported CompletionDataProvider
and use CompletionData.Consumer
to access the setAllCamos
callback for the image click handler.在导入的
CompletionDataProvider
中包装图像和CamoList
组件“对”,并使用CompletionData.Consumer
访问图像单击处理程序的setAllCamos
回调。
import React from "react";
import CamoList from "../Completion/CamoList";
import { useState } from "react";
import CompletionDataProvider, { CompletionData } from "../../hooks/getInfo";
export default function AR_LIST() {
const [damascusPercent, setDamascusPercent] = useState(0);
return (
<>
<h1>Assault Rifle</h1>
<div className="gun-grid">
<CompletionDataProvider>
<div>
<h1>ASM10</h1>
<CompletionData.Consumer>
{({ setAllCamos }) => (
<img
src="https://i.imgur.com/4rk88oj.jpg"
alt="ASM10"
onDoubleClick={setAllCamos}
/>
)}
</CompletionData.Consumer>
<CamoList
damascusPercent={damascusPercent}
setDamascusPercent={setDamascusPercent}
/>
</div>
</CompletionDataProvider>
...
</div>
</>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.