ReactJS: как динамически отображать Material-пользовательского интерфейса внутри ?

#javascript #css #reactjs #react-jsx #material-ui

#javascript #css #reactjs #материал-пользовательский интерфейс

Вопрос:

Используя ReactJS Material-UI, у меня есть вызываемый массив colors , содержащий строки разных цветов. Скажем, например, массив colors имеет 3 цветовые строки: «белый», «синий», «зеленый. Затем я хотел бы, чтобы каждая строка цвета имела <MenuItem/> внутри <DropDownMenu/> (http://www.material-ui.com/#/components/dropdown-menu ). И как только <MenuItem/> выбран параметр a, я бы хотел, чтобы консоль регистрировала этот конкретный цвет, например, выбрала «белый»: console.log(«белый»).

Итак, я использовал .forEach, но он не показывает никаких строк и пуст. Что я могу делать неправильно?

Вот код:

   constructor() {
    super()

    this.state = {
      value: 1,
    }
  }

  dropDownColorChange(event, index, value) {
    this.setState({value: value})
    //Not sure how to implement here dynamically based on array size. Would like to console.log the color string of the selected
  }

  render() {
    var colors = ["white", "blue", "green"] //would be able to handle any array size


    return (
             <div>
               <DropDownMenu
                value={this.state.valueTwo}
                onChange={this.dropDownColorChange}
              >
                {
                    <MenuItem value={1} primaryText="Select" />
                  colors.forEach(color => {
                    <MenuItem primaryText={color}/>
                  })
                }
              </DropDownMenu>
             </div>
    )
  }
  

Спасибо

Ответ №1:

Вы почти все поняли правильно. Вы должны map выбрать доступные цвета и вернуть a MenuItem для каждого цвета:

 const colors = ['white', 'blue', 'green'];

class ColorChanger extends Component {
  constructor() {
    super();

    this.state = {
      selectedColorValue: 1,
    };
  }

  handleColorChange(event, index, value) {
    console.log(`You have selected ${colors[value]} color`);

    this.setState({
      selectedColorValue: value
    });
  }

  render() {
    return (
      <div>
        <DropDownMenu value={this.state.selectedColorValue} onChange={this.handleColorChange}>
          {colors.map((color, index) =>
            <MenuItem key={index} value={index} primaryText={color} />
          )}
        </DropDownMenu>
      </div>
    );
  }
}
  

map (вопреки forEach ) возвращает массив, где каждый элемент является возвращаемым значением функции-предиката. В вашем случае он возвращает a <MenuItem /> .

Комментарии:

1. Вам нужно будет добавить key свойство в MenuItem, чтобы React мог отслеживать каждый элемент меню

2. Правильно, пропустил это. Ответ обновлен.

3. Я делаю то же самое, но событие onchange по какой-либо причине не работает с динамически созданным menuitem .

Ответ №2:

Я использовал хук реакции для установки пунктов меню при нажатии на значок моего меню, а также установил значение, которое я хочу передать своему методу действия.

 const [menuItems, setMenuItems] = React.useState<IMenuItem[]>();
const [menuValue, setMenuValue] = React.useState<IMenuValue>();

const handleClickMenu = (
    event: React.MouseEvent<HTMLElement>,
    value: IMenuValue,
  ) => {
    setMenuItems(value.menuItems);
    setMenuTransaction(value);

    setMenuAnchorEl(event.currentTarget);
  };


return (

// ... code ...
<PositionedVertMenu
 data-testid={`menu`}
 open={Boolean(menuAnchorEl)}
 anchorEl={menuAnchorEl}
 onClick={(event: React.MouseEvent<HTMLElement>) => handleClickMenu(event, value)}
 onClose={handleCloseMenu}
>
  {menuValue amp;amp;
   menuItems?.map((option, menuIndex) => (
    <MenuItem
     data-testid={`menu-item-${menuIndex}`}
     onClick={() => option.action(menuValue, handleCloseMenu)}
    >
     <Typography>{translate(option.text)}</Typography>
    </MenuItem>
   ))}
 </PositionedVertMenu>
)