У меня есть компонент, который получает дочерний элемент и передает его в MUI Menu

export default function MyMenu({children}){
    return(
        <Menu>
            {children ? children : <MenuItem disabled></MenuItem>}
          </Menu>
    );
}

Дочерние элементы имеют тип children: ReactNode;

И я передаю ему пункты меню так

<MyMenu>
{condition && (<MenuItem></MenuItem>)}
{condition2 && (<MenuItem></MenuItem>)}
</MyMenu>

Я хочу, чтобы при невыполнении всех условий отображался отключенный пункт меню
Проблема в том, что child никогда не бывает нулевым, если я передаю дочерние элементы, как указано выше. И из-за этого отключенного пункта меню никогда не отображается
Если все условия ложны, то child является массивом ложных значений. Но в коде я не могу обрабатывать child prop как массив, чтобы проверить, содержит ли он только ложные значения.

0
RheinmetallSkorpion 4 Фев 2022 в 13:31

3 ответа

Лучший ответ

Как насчет использования React.Children.toArray:

const MyMenu = ({ children }) => {
  const hasChildren = React.Children.toArray(children)
    .filter(Boolean)
    .length > 0
  
  if (hasChildren) {
    return children
  }

  return <MenuItem disabled />
}

Примечание: не тестировалось.

2
Marces Engel 4 Фев 2022 в 14:01
Это работает, спасибо
 – 
RheinmetallSkorpion
4 Фев 2022 в 14:04
Хороший подход, он работает: codesandbox.io/s/reactjs-lab-n791v?file=/src/labPages/…
 – 
PS-PARSA
4 Фев 2022 в 14:04

Вы можете отфильтровать массив children (если это не массив, это будет примитивное значение), чтобы удалить из него нулевые значения, вот пример:

const MyMenu = ({ children }) => {
  const tmp = Array.isArray(children)
    ? compact(children)
    : isNil(children)
    ? undefined
    : children;

  return <div>{tmp || tmp.length > 0 ? tmp : "DISABLED"}</div>;
};

Песочница: https:/ /codesandbox.io/s/reactjs-lab-n791v?file=/src/labPages/Experiments/test_files/8/index.jsx

0
PS-PARSA 4 Фев 2022 в 14:00

Можете ли вы использовать React.Children.count(children) и попробовать:

export default function MyMenu({children}){
    
   return(
        <Menu>
            {React.Children.count(children) ? children : <MenuItem disabled></MenuItem>}
          </Menu>
    );
}
0
Tushar Shahi 4 Фев 2022 в 13:41
Нет, это всегда приводит к 2. Даже если я передаю ребенку вот так {condition ? (<MenuItem></MenuItem>) : null}, он дает мне массив нулей
 – 
RheinmetallSkorpion
4 Фев 2022 в 13:50
ТОгда вы не можете проверить {children.length ? children : <MenuItem disabled></MenuItem>} ?
 – 
Tushar Shahi
4 Фев 2022 в 13:53
children имеет тип ReactNode. У него нет метода длины
 – 
RheinmetallSkorpion
4 Фев 2022 в 13:57