Вам необходимо удалить эту строку setRecords(props.records)
, потому что она вызывает изменение состояния на каждом рендере, который равен бесконечному l oop, который у вас есть.
Более того, вам также не нужна эта строка const [records, setRecords] = useState([]);
и вы можете просто отображать записи, которые у вас есть в подпорках, здесь нет необходимости в местном состоянии.
Более того, некоторые советы:
- Кажется, вы пытаетесь построить и отобразить Дерево сотрудников в то же время, что очень сложно, вы должны построить данные, которые необходимо отобразить, прежде чем отобразить его. Чтобы построить дерево из массива, посмотрите этот ответ stackoverflow
Это будет выглядеть так:
function Inhook(props) {
const initialState = 0;
const records = props.records
const sortedRecords = records.sort((x, y) => (x.empName.toLowerCase() > y.empName.toLowerCase()) * 2 - 1)
const employeeTree = createEmployeeTree(sortedRecords)
return (
<div>
<React.Fragment>
<br />
<div className="Tree">
<h1 style={{ textAlign: 'center' }}>Employee Tree</h1>
<h3>Test Case 1</h3>
<h4>Employee Tree</h4>
{employeeTree.map(manager => {
return (
<ul key={manager.id}>
<li style={{ fontWeight: 'bold' }}>
<p>
Employees of :
{manager.empName.toLowerCase()}
</p>
<ul>
{manager.children.map(employee => (
<li type="square" key={employee.id}>
{employee.empName.toLowerCase()}
{employee.children.map(e => (
<div>
<li
key={e.id}
type="disc"
style={{
marginLeft:
'120px',
}}>
{e.empName.toLowerCase()}
</li>
</div>
))}
</li>
))}
</ul>
</li>
</ul>
);
})}
</div>
</React.Fragment>
</div>
);
}
// Convert flat array to tree, see https://stackoverflow.com/a/40732240/6695569
const createEmployeeTree = data => {
let hashTable = {};
data.forEach(
aData => (hashTable[aData.id] = { ...aData, children: [] })
);
let dataTree = [];
data.forEach(aData => {
if (aData.managerId) {
if (!hashTable[aData.managerId]) return;
hashTable[aData.managerId].children.push(hashTable[aData.id]);
} else dataTree.push(hashTable[aData.id]);
});
return dataTree;
};
- Еще один совет, дон не используйте локальное состояние для производных значений, например, ваше
show
состояние было установлено в true, когда count
было больше 0. Тогда вам нужно просто использовать вычисленное значение const show = count >0
:
// instead of this
const [count, setCount] = useState(initialState);
const [show, setShow] = useState(false);
function(){
setCount(0)
setShow(false)
...
if(count > 0) setShow(true)
else setShow(false)
}
//do This
const [count, setCount] = useState(initialState);
const show = count > 0
- Еще один совет, JSX очень легко разбить на компоненты, так что делайте это и не делайте очень длинные рендеры, которые могут быть очень трудными для чтения, вы можете разделить это так:
function Inhook(props) {
return (
<div>
<Title />
<Managers employeeTree={employeeTree} />
</div>
)
}
function Title(){
return <h1 style={{ textAlign: 'center' }}>Employee Tree</h1>
}
function Managers({ employeeTree }) {
return (
<ul>
{employeeTree.map(manager => (
<li style={{ fontWeight: 'bold' }}>
<p>Employees of :{manager.empName.toLowerCase()}</p>
<Employees employees={manager.children} />
</li>
))}
</ul>
);
}
function Employees({ employees }) {
return (
<ul>
{employees.map(employee => (
<li type="square" key={employee.id}>
{employee.empName.toLowerCase()}
{employee.children.map(e => (
<div>
<li
key={e.id}
type="disc"
style={{
marginLeft: '120px',
}}>
{e.empName.toLowerCase()}
</li>
</div>
))}
</li>
))}
</ul>
);
}