Save question #15865
I have a function that needs to be called when componentDidMount and handleClick.
On the class component, there is no problem, but I converted to a React Hook function, inside the useEffect, mocking componentDidMount and calling this function. Outside the element, by clicking on the event, we also need to call this function to trigger the new calculation.
function App() {
const [elePositionArr, setElePositionArr] = useState([
{ left: 0, top: 0 },
{ left: 0, top: 0 },
{ left: 0, top: 0 }
]);
const stageRef = useRef(null);
const Stage = useRef({ w: 0, h: 0 });
const currentIndex = useRef(0);
useEffect(() => {
// Record the size of the stage when componentDidMount, Important!!!
const stageW = stageRef.current.scrollWidth;
const stageH = stageRef.current.scrollHeight;
Stage.current = { w: stageW, h: stageH };
const index = Math.floor(Math.random() * 3);
currentIndex.current = index;
// Randomly set the position of the element
setCenterPosition(index);
}, []);
// Centering a block element
function setCenterPosition(index) {
let cacheEle = elePositionArr;
// calc center postion
const centerOfLeft = Stage.current.w / 2 - 25;
const centerOfTop = Stage.current.h / 2 - 25;
cacheEle = cacheEle.map((item, i) => {
const randomWNum = Math.floor(Math.random() * Stage.current.w) - 50;
const randomHNum = Math.floor(Math.random() * Stage.current.h) - 50;
const randomLeft = randomWNum <= 50 ? 50 : randomWNum;
const randomTop = randomHNum <= 50 ? 50 : randomHNum;
let newItem;
if (index === i) {
newItem = { left: centerOfLeft, top: centerOfTop };
} else {
newItem = { left: randomLeft, top: randomTop };
}
return newItem;
});
setElePositionArr(cacheEle);
}
// click nav li, then setElePositionArr
function handleClickLi(index) {
if (currentIndex.current !== index) {
setCenterPosition(index);
currentIndex.current = index;
}
}
return (
<div className="container">
<div className="stage" ref={stageRef}>
{elePositionArr.map((item, index) => (
<div className="ele" key={index} style={item}>
{index}
</div>
))}
</div>
<ul className="nav">
{elePositionArr.map((item, index) => (
<li
className={currentIndex.current === index ? "active-li" : ""}
onClick={() => {
handleClickLi(index);
}}
key={"li" + index}
>
{index}
</li>
))}
</ul>
</div>
);
}
So, React Hook will prompt:
React Hook useEffect has a missing dependency: 'setCenterPosition'.
Either include it or remove the dependency array. (react-hooks/exhaustive-deps)
I didn't find a suitable answer in the 8. Hooks FAQ. Can someone help me?
codesandbox
https://codesandbox.io/s/trusting-kowalevski-oet4b
not sure what answer you are looking for here. But, general problem is you are trying to make this act like a class component instead of embracing how the hooks work. For instance setCenterPosition is defined twice because it's called again in handleClickLi. But you don't need to do that. Instead write your useEffect so it runs when you need it to: _in response to the changing index_. Then you don't need the function you can put all the logic in useEffect.
In the general you don't want to think in terms of "How do i map useEffect to component lifecycles", instead structure them to run when the things they depend on change.
Here is one example of how you might do that: https://codesandbox.io/s/magical-wildflower-d8gp0
@jquense Thank you very much for providing a solution,my problem may be a hook conversion based on the form of class, so the understanding of useEffect is not deep enough, as you said, instead structure them to run when the things they depend on change.
Most helpful comment
not sure what answer you are looking for here. But, general problem is you are trying to make this act like a class component instead of embracing how the hooks work. For instance
setCenterPositionis defined twice because it's called again inhandleClickLi. But you don't need to do that. Instead write your useEffect so it runs when you need it to: _in response to the changing index_. Then you don't need the function you can put all the logic in useEffect.In the general you don't want to think in terms of "How do i map useEffect to component lifecycles", instead structure them to run when the things they depend on change.
Here is one example of how you might do that: https://codesandbox.io/s/magical-wildflower-d8gp0