我使用D3和react useEffect
钩子,我用useCallback
钩子 Package 了click方法并更新了状态,但是当我点击元素时,元素状态根本没有更新。为了停止重新渲染D3 SVG元素,我不想将counter
作为依赖项添加到useEffect
钩子。
我可以更新counter
状态而不添加counter
对useEffect
的依赖关系吗?
CodeSandbbox
import { useEffect, useState, useCallback } from "react";
import * as d3 from "d3";
export default function App() {
const [counter, setCounter] = useState(0);
const handleClick = useCallback(() => {
setCounter(counter + 1);
console.log(counter);
}, [counter]);
useEffect(() => {
const svg = d3.select("#svg");
//naming the selection
const redRect = svg
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 300)
.attr("height", 300)
.attr("fill", "red")
.attr("id", "red-rect");
redRect.on("click", handleClick);
}, []); // should not re-render the d3 with counter as the dependency
return <svg id="svg" />;
}
2条答案
按热度按时间x8diyxa71#
我已经找到了阻止useEffect的方法,用
useRef
重做所有D3的东西,我使用useRef值作为D3 SVG rect
,然后我检查rectRef.current
是否存在,然后忽略D3方法并将handleClick
绑定到rectRef.current
。CodeSandbox
mccptt672#
向
setCounter
传递一个函数。该函数的参数是状态的前一个值。useCallback
在这里是不必要的,因为setCounter
不会改变标识。useReducer
也是一个更好的钩子,只用于增量。Code Sandbox
片段
一个一个二个一个一个一个三个一个一个一个一个一个四个一个