Compare commits

..

2 Commits

Author SHA1 Message Date
laktionov-as 12515f925d Сделали таймер 2026-05-28 20:45:57 +03:00
laktionov-as b3662b759f class components 2026-05-28 20:29:26 +03:00
4 changed files with 101 additions and 90 deletions
+1 -69
View File
@@ -9,9 +9,7 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0"
"react-error-boundary": "^6.1.2",
"react-router-dom": "^7.17.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.25.0", "@eslint/js": "^9.25.0",
@@ -1602,19 +1600,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/cookie": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
"integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.6", "version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2476,15 +2461,6 @@
"react": "^19.1.0" "react": "^19.1.0"
} }
}, },
"node_modules/react-error-boundary": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.2.tgz",
"integrity": "sha512-3DpCr5HVdZ0caUjYE/kIHBEJN0mNP3ZCgf16c48uJ5TbWjorKVp+YG8W3XqlJ7vJAVNw6wNIImyPXmFydwmyng==",
"license": "MIT",
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0"
}
},
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.17.0", "version": "0.17.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
@@ -2495,44 +2471,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-router": {
"version": "7.17.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.17.0.tgz",
"integrity": "sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/react-router-dom": {
"version": "7.17.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.17.0.tgz",
"integrity": "sha512-fyU2yjGups/hE6Xz0I5ZYbVL8Gx29eCjgpHaRaTaVU+OOAdfRX05KsvyRm0GO8YQwOkhpU3MurW1jyMUJn+zSw==",
"license": "MIT",
"dependencies": {
"react-router": "7.17.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
}
},
"node_modules/resolve-from": { "node_modules/resolve-from": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -2606,12 +2544,6 @@
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
}, },
"node_modules/set-cookie-parser": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
"license": "MIT"
},
"node_modules/shebang-command": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+1 -3
View File
@@ -11,9 +11,7 @@
}, },
"dependencies": { "dependencies": {
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0"
"react-error-boundary": "^6.1.2",
"react-router-dom": "^7.17.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.25.0", "@eslint/js": "^9.25.0",
+98 -15
View File
@@ -1,25 +1,108 @@
import { Suspense, lazy } from 'react' import React from 'react'
import { ErrorBoundary } from 'react-error-boundary'
const LazyComponent = lazy(() => import('./MyComponent')) class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { data: null };
this.handleClick = this.handleClick.bind(this);
}
function ErrorFallBack({error, resetErrorBoundary }) { render() {
return ( return (
<div> <div>
<h2>Что то сломалось</h2> {this.state.data ? (
<button onClick={resetErrorBoundary}></button> <div>Данные: {this.state.data}</div>
</div> ) : (
) <div>Загрузка...</div>
)}
<button onClick={this.handleClick}>Обновить</button>
</div>
)
}
componentDidMount() {
fetch('https://api.example.com/data')
.then(responce => responce.json())
.then(json => this.setState({data: json}));
this.timerId = setInterval(()=> console.log('Tick'), 1000);
}
componentWillUnmout() {
clearInterval(this.timerId);
}
handleClick() {
this.setState({data: 'Данные'})
}
}
class MyComponent2 extends React.Component {
controller = new AbortController()
componentDidMount() {
fetch('https://api.example.com/data',{ singnal: this.controller.signal })
.then(responce => responce.json())
.then(json => this.setState({data: json}))
.catch(error => {
if(error.name == 'AbortError') {
console.log('Aborted');
} else {
console.log('Other error',error);
}
});
}
componentWillUnmount() {
this.controller.abort()
}
}
class MyComponent3 extends React.Component {
componentDidMount() {
this.loadData();
}
async loadData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
this.setSate({ data });
} catch {
console.log('error');
}
}
}
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { seconds: 0 }
}
componentDidMount() {
console.log('Timer mounted');
this.interval = setInterval(()=>{
this.setState(prevState => ({seconds: prevState.seconds + 1}))
},1000);
}
componentWillUnmount() {
console.log('Timer unmount');
clearInterval(this.interval);
}
render() {
return <h2>Прошло секунд: {this.state.seconds}</h2>
}
} }
function App() { function App() {
const [show,setShow] = React.useState(true);
return ( return (
<> <>
<ErrorBoundary FallBackComponent={ErrorFallBack}> <h1>Таймер с классом</h1>
<Suspense fallback={<div>Загрузка ...</div>}> <button onClick={()=>setShow(prev => !prev)}>{show ? 'Скрыть' : 'Показать'} таймер</button>
<LazyComponent /> {show && <Timer />}
</Suspense>
</ErrorBoundary>
</> </>
) )
} }
-2
View File
@@ -4,7 +4,5 @@ import { createRoot } from 'react-dom/client'
import App from './App.jsx' import App from './App.jsx'
createRoot(document.getElementById('root')).render( createRoot(document.getElementById('root')).render(
<StrictMode>
<App /> <App />
</StrictMode>
) )