我有一个使用上下文变量并且工作正常的查看器组件。我想为此查看器实现一些自定义扩展,我将它们的声明放在 useEffect 挂钩中,仅运行一次,它们就被注册了。
在这些扩展中,我有一些按钮,它们在
onToolbarCreated
中加载,并且onClick函数使用React Context变量,但它们返回未定义或初始值,如何让它们识别这些变量?
代码:
function Viewer() {
const {
setMainViewer,
isTreeActive,
isIssuesListActive,
isBlueprintsListActive,
isIssueDatailsActive,
setCurrentIssueSelected,
currentIssueSelected,
} = useContext(AppContext);
useEffect(() => {
const auxinitViewer = async () => {
setMainViewer(
await initViewer(document.getElementById("mainViewerDiv"))
);
};
initExtensions();
auxinitViewer();
}, []);
const initExtensions = async () => {
// TOOLBAR EXTENSION
function UpperViewPanel(viewer, options) {
//... code
}
UpperViewPanel.prototype = Object.create(
Autodesk.Viewing.UI.DockingPanel.prototype
);
UpperViewPanel.prototype.constructor = UpperViewPanel;
function ToolbarExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
}
ToolbarExtension.prototype = Object.create(
Autodesk.Viewing.Extension.prototype
);
ToolbarExtension.prototype.constructor = ToolbarExtension;
ToolbarExtension.prototype.load = function () {
this.viewer.fitToView();
return true;
};
ToolbarExtension.prototype.unload = function () {
if (this.subToolbar) {
this.viewer.toolbar.removeControl(this.subToolbar);
this.subToolbar = null;
}
};
var button3 = new Autodesk.Viewing.UI.Button("enable-upper-view");
ToolbarExtension.prototype.onToolbarCreated = async function (toolbar) {
var mainViewer = this.viewer;
const upper_view_panel_div =
document.getElementById("upper-view-panel");
if (upper_view_panel_div) {
upper_view_panel_div.remove();
}
let panel;
if (mainViewer.model.is3d()) {
panel = new UpperViewPanel(this.viewer, null);
panel.initViewer();
}
button3.onClick = function (e) {
// HERE IS THE PROBLEM, currentIssueSelected is always undefined
console.log("CURRENT ISSUE SELECTED", currentIssueSelected);
if (!currentIssueSelected) {
showErrorToasty(
"Não é possível ver planta sem um problema selecionado"
);
} else {
if (!currentIssueSelected.linkedDocuments[0]) {
showErrorToasty(
"Este problema não contém posicionamento"
);
} else {
if (
panel.getVisibility().display === "block" &&
panel.getVisibility().zIndex === "-1"
) {
panel.setIssue(currentIssueSelected);
panel.setVisible();
button3.removeClass("top_view");
button3.addClass("top_view_selected");
} else if (panel.getVisibility().display === "none") {
panel.setIssue(currentIssueSelected);
panel.setVisible();
button3.removeClass("top_view");
button3.addClass("top_view_selected");
} else if (
panel.getVisibility().display === "block" &&
panel.getVisibility().zIndex === "0"
) {
panel.setIssue(currentIssueSelected);
}
}
}
};
button3.removeClass("top_view_selected");
button3.addClass("top_view");
button3.setToolTip("Mostrar planta");
var issues_combo_button = new Autodesk.Viewing.UI.ComboButton(
"issues_combo_button"
);
issues_combo_button.setIcon("issues_combo_button");
issues_combo_button.onMouseOver = function (e) {
issues_combo_button.setIcon("issues_combo_button_selected");
};
issues_combo_button.onMouseOut = function (e) {
issues_combo_button.setIcon("issues_combo_button");
};
var utils_combo_button = new Autodesk.Viewing.UI.ComboButton(
"utils_combo_button"
);
utils_combo_button.setIcon("utils_combo_button");
utils_combo_button.onMouseOver = function (e) {
utils_combo_button.setIcon("utils_combo_button_selected");
};
utils_combo_button.onMouseOut = function (e) {
utils_combo_button.setIcon("utils_combo_button");
};
this.subToolbar = new Autodesk.Viewing.UI.ControlGroup(
"my-custom-toolbar"
);
this.subToolbar2 = new Autodesk.Viewing.UI.ControlGroup(
"my-custom-toolbar2"
);
if (mainViewer.model.is3d()) {
utils_combo_button.addControl(button3);
}
this.subToolbar.addControl(issues_combo_button);
// SubToolbar
toolbar.addControl(this.subToolbar);
if (mainViewer.model.is3d()) {
this.subToolbar2.addControl(utils_combo_button);
toolbar.addControl(this.subToolbar2);
}
};
Autodesk.Viewing.theExtensionManager.registerExtension(
"ToolbarExtension",
ToolbarExtension
);
};
const handleViewerWidth = () => {
//...
};
return (
<div
style={{
width: handleViewerWidth(),
height: "100%",
position: "absolute",
left: `${
isTreeActive || isIssuesListActive || isBlueprintsListActive
? "23%"
: "3%"
}`,
}}
id="mainViewerDiv"
/>
)}
在上面的示例中,您可以看到我在button3 onClick 中使用了上下文变量
currentIssueSelected
,但它始终是未定义的,我已经尝试过:
Viewer({currentIssueSel}){...}
;有什么建议吗?
这个问题可能与 onClick 函数定义和执行的时间有关,因此您可以尝试使用 useEffect 钩子在上下文值发生变化时更新 onClick 函数。useEffect 及其依赖数组中带有 currentIssueSelected 可以确保每当 currentIssueSelected 发生变化时,onClick 函数就会更新。
const [button3ClickHandler, setButton3ClickHandler] = useState(() => {});
useEffect(() => {
setButton3ClickHandler(() => {
return function (e) {
console.log("CURRENT ISSUE SELECTED", currentIssueSelected);
if (!currentIssueSelected) {
showErrorToasty(
"Não é possível ver planta sem um problema selecionado"
);
} else {
// ... rest of your onClick logic ...
}
};
});
}, [currentIssueSelected]);
useEffect(() => {
const auxinitViewer = async () => {
setMainViewer(await initViewer(document.getElementById("mainViewerDiv")));
};
initExtensions();
auxinitViewer();
}, [currentIssueSelected]);
const initExtensions = async () => {
// ... your existing code ...
button3.onClick = button3ClickHandler;
// ... rest of your onToolbarCreated logic ...
};