Inline Babel script:147 Uncaught TypeError: Cannot read properties of undefined (reading 'length')
консоль выдаёт эту ошибку с length
. Нигде не могу найти ошибку.
Данные в data.js выглядит так:
const words = [
{
id: '1',
token: 'house',
word: 'Сasa',
type: 'word'
},
{
id: '2',
token: 'house',
url: 'img/photo-card-4.jpg',
type: 'image'
},
{
id: '3',
token: 'dog',
word: 'Сane',
type: 'word'
}, ...
window.words = words
а это основной код:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pics to word</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="root">
<script type="text/babel">
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<App words={words}/>)
function GameHeader({value, max, errorsCount, finishedItems}) {
return (
<>
<img src="img/pics-to-words.svg" width="112" height="16" alt="pics to words"/>
<Progress value={finishedItems.length} max={words.length}/>
<Hearts count={3} value={errorsCount}/>
</>
)
}
function Hearts({count = 0, value = 0}) {
return (
<p className="hit-points-indicator">
{Array(count).fill(null).map((_, i) => (
<span className={i < value ? 'hit=points-used' : 'hit-points-unused'}/>
))}
</p>
)
}
function Progress({value, max}) {
return (
<div className="progress-wrapper">
<div className="progress" style={{width: `${(max - value) / max * 100}%`}}></div>
</div>
)
}
function Grid({words, finishedItems, checkItems}) {
const [selectedItems, setSelectedItems] = React.useState([])
const handleCardClick = (id) => {
if (selectedItems.includes(id)) {
return
}
switch (selectedItems.length) {
case 0:
setSelectedItems([id])
break
case 1:
setSelectedItems((items) => [...items, id])
checkItems(selectedItems[0], id)
setTimeout(() => {
setSelectedItems([])
}, 800)
break
default:
setSelectedItems([])
}
}
const cards = words.map((item) => (
<Card
key={item.id}
item={item}
isSelected={selectedItems.includes(item.id)}
isFinished={finishedItems.includes(item.id)}
isCheking={selectedItems.length === 2}
onCardClick={handleCardClick}
/>
))
return (
<ul className="cards">
{cards}
</ul>
)
}
function Card({item, isSelected, isFinished, onCardClick, isCheking}) {
const {type, url, word: text, id} = item
const content = type === 'image'
? <img src={url} width="185" height="100" alt="card"/>
: <span>{text}</span>
const showError = isCheking && isSelected && !isFinished
const className = `card ${
isSelected ? 'selected' : ''
} ${
isFinished ? 'disabled' : ''
}`
const handleClick = () => {
if (isFinished) {
return
}
onCardClick(id)
}
return (
<li className={className} onClick={handleClick}>
{content}
</li>
)
}
const useGame = (words) => {
const [finishedItems, setFinishedItems] = React.useState([]);
const [stepsCount, setStepsCount] = React.useState(0);
const checkItems = (firstItem, secondItem) => {
const firstWord = words.find(({id}) => id === firstItem);
const secondWord = words.find(({id}) => id === secondItem);
if (firstWord && secondWord && firstWord.type === secondWord.type) {
return;
}
if (firstWord.token === secondWord.token) {
setFinishedItems((items) => [...items, firstItem, secondItem]);
}
setStepsCount((i) => i + 1);
};
const handleReset = () => {
setFinishedItems([]);
setStepsCount(0);
};
const errorsCount = stepsCount - finishedItems.length / 2;
const lives = 3 - errorsCount;
const isWin = finishedItems.length === words.length;
const isGameOver = isWin || lives === 0;
return (
finishedItems,
handleReset,
checkItems,
errorsCount,
isGameOver,
isWin
);
};
function App({words = []}) {
const {finishedItems, handleReset, checkItems, errorsCount, isGameOver, isWin} = useGame(words);
const modalClassName = isWin ? '' : 'modal-box-lose'
const modalCaption = isWin ? 'Победа' : 'Поражене'
const modalDescription = `Вы нашли ${finishedItems.length / 2} слова`
return (
<section className="game">
<GameHeader value={finishedItems.length} max={words.length} errorsCount={errorsCount} />
<Grid words={words} finishedItems={finishedItems} checkItems={checkItems} />
{isGameOver && (
<Modal
className={isWin ? "" : "modal-box-lose"}
caption={isWin ? "Победа" : "Поражение"}
description={`Вы нашли ${finishedItems.length / 2} слова`}
onReset={handleReset}
/>
)}
</section>
);
}
//root.render(<App words={words} />);
</script>
</div>
<script src="vendor/react.development.js"></script>
<script src="vendor/react-dom.development.js"></script>
<script src="vendor/babel.min.js"></script>
<script src="data.js"></script>
<script src="settings.js"></script>
</body>
</html>