javascript - 如何使用属性中的状态表达式动态创建 React 元素 (material-ui)

标签 javascript reactjs material-ui next.js

我想在功能组件中动态创建material-ui上下文菜单。因此,我使用如下状态

 let legendContextMenuStatesObject = {};
  for (let key of keys) {
    legendContextMenuStatesObject[key] = initialState;
  }
  const [legendContextMenuStates, setLegendContextMenuStates] = useState(
    legendContextMenuStatesObject
  );

初始状态是

 const initialState = {
  mouseX: null,
  mouseY: null
};

右键单击某些区域后,我将相应的状态对象更改为鼠标事件位置。然后应该会弹出以下菜单。

  function contextMenus(keys) {
    console.log(keys);
    const menues = [];
    for (let key of keys) {
      menues.push(
        <Menu
          keepMounted
          open={legendContextMenuStates[key].mouseY !== null}
          onClose={props.onClose}
          anchorPosition={
            legendContextMenuStates[key].mouseY !== null &&
            legendContextMenuStates[key].mouseX !== null
              ? {
                  top: legendContextMenuStates[key].mouseY,
                  left: legendContextMenuStates[key].mouseX
                }
              : undefined
          }
          anchorReference="anchorPosition"
          TransitionComponent={Fade}
        >
          <MenuItem onClick={event => handleClickLegendContextMenu(event, key)}>
            Line style
          </MenuItem>
        </Menu>
      );
    }
    return menues;
  }

状态更改确实有效,但菜单不出现。 据我了解这个问题,代码行

open={legendContextMenuStates[key].mouseY !== null}

在创建菜单元素时进行评估,而不是插入表达式使元素可以通过状态更改进行控制。 事实上,我通过静态实现让上下文菜单在不同的页面上工作,这意味着我对每个菜单进行硬编码,而不是在循环中创建它们。

我有办法阻止立即评估开放属性并实际保留我想要的表达式吗?

非常感谢任何帮助!

干杯

最佳答案

问题是我在状态中嵌套了对象。这样,即使 useEffect 也无法识别状态的任何变化。 我通过使用状态对象解决了这个问题,如下所示

 let legendContextMenuStates = {};
  for (let key of keys) {
    legendContextMenuStates[key] = useState(initialState);
  }

现在一切正常;还动态创建菜单:

 function contextMenus() {
    const menus = [];
    for (let key of keys) {
      menus.push(
        <Menu
          keepMounted
          open={legendContextMenuStates[key][0].mouseY !== null}
          onClose={() => {
            legendContextMenuStates[key][1](initialState);
          }}
          anchorPosition={
            legendContextMenuStates[key][0].mouseY !== null &&
            legendContextMenuStates[key][0].mouseX !== null
              ? {
                  top: legendContextMenuStates[key][0].mouseY,
                  left: legendContextMenuStates[key][0].mouseX
                }
              : undefined
          }
          anchorReference="anchorPosition"
          TransitionComponent={Fade}
        >
          <MenuItem onClick={event => handleClickLegendContextMenu(event, key)}>
            Color
          </MenuItem>
          <MenuItem onClick={event => handleClickLegendContextMenu(event, key)}>
            Line style
          </MenuItem>
          <MenuItem onClick={event => handleClickLegendContextMenu(event, key)}>
            Line width
          </MenuItem>
          <MenuItem onClick={event => handleClickLegendContextMenu(event, key)}>
            Curve style
          </MenuItem>
        </Menu>
      );
    }
    return menus;
  }

关于javascript - 如何使用属性中的状态表达式动态创建 React 元素 (material-ui),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60743504/

相关文章:

javascript - Material-UI 菜单问题

javascript - 如何将多行单元格拆分为 Google 表格的数组?

javascript - 浏览器后退按钮和 javascript

javascript - watchify 和 gulp.watch 的区别

reactjs - 将 Material-ui 自定义主题与 redux 结合使用

reactjs - 即使使用 enableReinitialize,Formik FieldArray 也不会重新渲染更新的值

javascript - 如何实现注销返回登录页面的功能?

reactjs - React Material-ui 响应式布局

javascript - 将 div 放在链接内 - 区域在 div 外仍可点击

javascript - 如何让 angularJS routeProvider 在路由更改之前执行操作?