无法通过回调访问反应状态

时间:2020-05-22 23:07:06

标签: javascript reactjs typescript visnetwork

我具有以下组成部分:

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内部访问networkData的{​​{1}}状态。我知道这是不可能的,但是有任何解决方法吗?此时,我还需要访问options.manipulation.addEdge

1 个答案:

答案 0 :(得分:2)

在这种情况下,您需要useRef。看来const network = new vis.Network(container, networkData, options);仅使用第一个渲染中的选项。或类似的事情正在发生。

这可能与newType函数中addEdge周围的闭包有关。因此它具有过时的值: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
}