无法从回调访问反应状态
Cannot access react state from callback
我有以下组件:
const ParentComponent: React.FC = () => {
// Somewhere in the code, I set this to some value
const [newType, setNewType] = useState<any>(undefined);
// Somewhere in the code, I set this to true
const [enableAddEdge, setEnableAddEdge] = useState(false);
const addEdge = (data: any) => {
console.log("newType", newType); // This is undefined
}
return (
...
<VisNetwork
newType={newType}
onAddEdge={addEdge}
enableAddEdge={enableAddEdge}
/>
...
)
}
export default ParentComponent;
interface Props {
newType: any;
onAddEdge: (data: any) => void;
enableAddEdge: boolean;
}
const VisNetwork: React.FC<Props> = (props: Props) => {
const options: any = {
// Some vis-network specific option configuration
manipulation: {
addEdge: (data: any, callback: any) => props.onAddEdge(data);
}
}
...
// Some code to create the network and pass in the options
const network = new vis.Network(container, networkData, options);
useEffect(() => {
if (props.enableAddEdge) {
// This confirms that indeed newType has value
console.log("newType from addEdge", props.newType);
// Call reference to network (I name it currentNetwork)
// This will enable the adding of edge in the network.
// When the user is done adding the edge,
// the `addEdge` method in the `options.manipulation` will be called.
currentNetwork.addEdgeMode();
}
}, [props.enableAddEdge])
useEffect(() => {
if (props.newType) {
// This is just to confirm that indeed I am setting the newType value
console.log("newType from visNetwork", props.newType); // This has value
}
}, [props.newType]);
}
export default VisNetwork;
调用addEdge
方法时,newType
状态变为未定义状态。我知道绑定,但我不知道是否可以使用它以及如何在功能组件中使用它。请告知如何获得newType
值。
此外,从 VisNetwork
,我想从 options.manipulation.addEdge
内部访问 networkData
状态。我知道这是不可能的,但有什么解决方法吗?此时我还需要访问networkData
。
在这种情况下,您需要 useRef
。看来 const network = new vis.Network(container, networkData, options);
仅使用第一次渲染中的选项。或者类似的事情正在发生。
这可能与 addEdge
函数中围绕 newType
的闭包有关。所以它有过时的值:https://reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function
为了解决这个问题,您需要useRef
来存储newType
的最新值。引用是可变的,因此它可以始终存储 newType 的当前值而无需重新渲染。
// Somewhere in the code, I set this to some value
const [newType, setNewType] = useState<any>(undefined);
const newTypeRef = useRef(newType);
useEffect(() => {
// Ensure the ref is always at the latest value
newTypeRef.current = newType;
}, [newType])
const addEdge = (data: any) => {
console.log("newType", newTypeRef.current); // This is undefined
}
我有以下组件:
const ParentComponent: React.FC = () => {
// Somewhere in the code, I set this to some value
const [newType, setNewType] = useState<any>(undefined);
// Somewhere in the code, I set this to true
const [enableAddEdge, setEnableAddEdge] = useState(false);
const addEdge = (data: any) => {
console.log("newType", newType); // This is undefined
}
return (
...
<VisNetwork
newType={newType}
onAddEdge={addEdge}
enableAddEdge={enableAddEdge}
/>
...
)
}
export default ParentComponent;
interface Props {
newType: any;
onAddEdge: (data: any) => void;
enableAddEdge: boolean;
}
const VisNetwork: React.FC<Props> = (props: Props) => {
const options: any = {
// Some vis-network specific option configuration
manipulation: {
addEdge: (data: any, callback: any) => props.onAddEdge(data);
}
}
...
// Some code to create the network and pass in the options
const network = new vis.Network(container, networkData, options);
useEffect(() => {
if (props.enableAddEdge) {
// This confirms that indeed newType has value
console.log("newType from addEdge", props.newType);
// Call reference to network (I name it currentNetwork)
// This will enable the adding of edge in the network.
// When the user is done adding the edge,
// the `addEdge` method in the `options.manipulation` will be called.
currentNetwork.addEdgeMode();
}
}, [props.enableAddEdge])
useEffect(() => {
if (props.newType) {
// This is just to confirm that indeed I am setting the newType value
console.log("newType from visNetwork", props.newType); // This has value
}
}, [props.newType]);
}
export default VisNetwork;
调用addEdge
方法时,newType
状态变为未定义状态。我知道绑定,但我不知道是否可以使用它以及如何在功能组件中使用它。请告知如何获得newType
值。
此外,从 VisNetwork
,我想从 options.manipulation.addEdge
内部访问 networkData
状态。我知道这是不可能的,但有什么解决方法吗?此时我还需要访问networkData
。
在这种情况下,您需要 useRef
。看来 const network = new vis.Network(container, networkData, options);
仅使用第一次渲染中的选项。或者类似的事情正在发生。
这可能与 addEdge
函数中围绕 newType
的闭包有关。所以它有过时的值:https://reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function
为了解决这个问题,您需要useRef
来存储newType
的最新值。引用是可变的,因此它可以始终存储 newType 的当前值而无需重新渲染。
// Somewhere in the code, I set this to some value
const [newType, setNewType] = useState<any>(undefined);
const newTypeRef = useRef(newType);
useEffect(() => {
// Ensure the ref is always at the latest value
newTypeRef.current = newType;
}, [newType])
const addEdge = (data: any) => {
console.log("newType", newTypeRef.current); // This is undefined
}