【问题标题】:How to dynamically create React elements (material-ui) with state expressions in property如何使用属性中的状态表达式动态创建 React 元素(material-ui)
【发布时间】:2020-03-18 16:18:47
【问题描述】:

我想在功能组件中动态创建 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}

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

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

非常感谢任何帮助!

干杯

【问题讨论】:

    标签: javascript reactjs material-ui next.js


    【解决方案1】:

    问题是我在状态中嵌套了对象。这样,甚至 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;
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-01
      • 2016-04-02
      • 2021-09-12
      • 1970-01-01
      • 2019-09-30
      • 2016-04-02
      • 2018-01-02
      • 2020-06-01
      相关资源
      最近更新 更多