Как писать mobx на классовых компонентах react.ts
Хочу написать на react.ts mobx class component, но вылезает ошибка Cannot access 'Context' before initialization ReferenceError: Cannot access 'Context' before initialization
Вот код где вылезает ошибка:
//Header.tsx
import React, { Component, useContext } from 'react'
import '../style/Home.scss'
import Modal from 'react-bootstrap/Modal';
import Google from '../images/Google.png'
import FloatingLabel from 'react-bootstrap/FloatingLabel';
import Form from 'react-bootstrap/Form';
import Image from 'react-bootstrap/Image';
import Round from '../images/round.png'
import { Context } from '..'
import { observer } from 'mobx-react'
interface ExampleState {
showAuth: boolean;
showReg: boolean;
showReg2: boolean;
email:string;
password:string;
}
@observer
export default class Header extends React.Component<{}, ExampleState> {
constructor(props: {}) {
super(props);
this.state = {
showAuth: false,
showReg: false,
showReg2: false,
email:'',
password: '',
};
}
static store = Context
handleRegistration = (store: any) => {
const { email, password } = this.state;
store.registration('surname', 'name', 'lastname', email, password, 'color');
};
handleCloseAuth = () => {
this.setState({ showAuth: false });
};
handleShowAuth = () => {
this.setState({ showAuth: true });
};
handleCloseReg = () => {
this.setState({ showReg: false });
};
handleShowReg = () => {
this.setState({ showReg: true });
};
handleCloseReg2 = () => {
this.setState({ showReg2: false });
};
handleShowReg2 = () => {
this.setState({ showReg2: true });
this.setState({ showReg: false })
};
googleAuth = () => {
window.open(`${process.env.REACT_APP_API_URL}/auth/google/callback`, "_self");
};
render() {
const { showAuth } = this.state;
const { showReg } = this.state;
const { showReg2 } = this.state;
const { email } = this.state;
const { password } = this.state;
return (
<div className="header">
<div className="header__cont">
<div className="header__cont__left">
<p onClick={this.handleShowAuth}>Авторизация</p>
</div>
<div className="header__cont__center">
<h1>BOOKSWAP</h1>
</div>
<div className="header__cont__right">
<p onClick={this.handleShowReg}>Регистрация</p>
</div>
</div>
<Modal show={showAuth} onHide={this.handleCloseAuth}>
<Modal.Header closeButton className="custom-close-button">
<Modal.Title style={{margin:'0 auto', textAlign:'center', marginLeft:'8.5rem'}}>Авторизация</Modal.Title>
</Modal.Header>
<Modal.Body style={{height:'420px'}}>
<button className='btn-google' onClick={this.googleAuth}>
<div>
<img src={Google} alt="Google" />
<p>Войти через Google</p>
</div>
</button>
<div style={{display:'flex', margin:'0 auto', marginTop:'10px'}}>
<div className="horizontal-line"></div>
<p style={{color:'#F0A650'}}>или</p>
<div className="horizontal-line"></div>
</div>
<FloatingLabel
controlId="floatingInput"
label="Email"
className="mb-3"
style={{color:'#F0A650'}}
>
<Form.Control type="email" placeholder="[email protected]" />
</FloatingLabel>
<FloatingLabel controlId="floatingPassword" label="Пароль" style={{color:'#F0A650'}}>
<Form.Control type="password" placeholder="Password" />
</FloatingLabel>
<p className='a' style={{color:'#F0A650', fontWeight:'600', marginTop:'5px', fontSize:'16px'}}>Забыл пароль?</p>
<button className='btn-auth' style={{marginTop:'-5px'}}>Авторизоваться</button>
<p style={{display:'flex', marginTop:'10px'}}>Нет аккаунта?<p className='a' style={{color:'#F0A650', fontWeight:'600', marginLeft:'5px', fontSize:'16px'}}>Создать аккаунт</p></p>
</Modal.Body>
</Modal>
<Modal show={showReg} onHide={this.handleCloseReg}>
<Modal.Header closeButton className="custom-close-button">
<Modal.Title style={{margin:'0 auto', textAlign:'center', marginLeft:'9rem'}}>Регистрация</Modal.Title>
</Modal.Header>
<Modal.Body style={{height:'470px'}}>
<button className='btn-google'>
<div>
<img src={Google} alt="Google" />
<p>Зарегистрироваться через Google</p>
</div>
</button>
<div style={{display:'flex', margin:'0 auto', marginTop:'10px'}}>
<div className="horizontal-line"></div>
<p style={{color:'#F0A650'}}>или</p>
<div className="horizontal-line"></div>
</div>
<FloatingLabel
controlId="floatingInput"
label="Email"
className="mb-3"
style={{color:'#F0A650'}}
>
<Form.Control type="email" placeholder="[email protected]" value={this.state.email}
onChange={(e) => this.setState({ email: e.target.value })}/>
</FloatingLabel>
<FloatingLabel controlId="floatingPassword" label="Пароль" style={{color:'#F0A650'}}>
<Form.Control type="password" placeholder="Password" value={this.state.password}
onChange={(e) => this.setState({ password: e.target.value })}/>
</FloatingLabel>
<FloatingLabel controlId="floatingPassword" label="Повторите пароль" style={{color:'#F0A650', marginTop:'15px'}}>
<Form.Control type="password" placeholder="Password" />
</FloatingLabel>
<button className='btn-auth' style={{marginTop:'15px'}} onClick={this.handleRegistration}>Зарегистрироваться</button>
<p style={{display:'flex', marginTop:'10px'}}>Есть аккаунт?<p className='a' style={{color:'#F0A650', fontWeight:'600', marginLeft:'5px', fontSize:'16px'}}>Войти</p></p>
</Modal.Body>
</Modal>
<Modal show={showReg2} onHide={this.handleCloseReg2}>
<Modal.Header closeButton className="custom-close-button">
<Modal.Title style={{margin:'0 auto', textAlign:'center', marginLeft:'9rem'}}>Регистрация</Modal.Title>
</Modal.Header>
<Modal.Body style={{height:'560px'}}>
<div style={{margin:'0 auto', display:'flex', marginBottom:'15px'}}>
<Image src={Round} roundedCircle style={{width:'8rem', margin:'0 auto'}}/>
</div>
<FloatingLabel
controlId="floatingInput"
label="Фамилия"
className="mb-3"
style={{color:'#F0A650'}}
>
<Form.Control type="text" placeholder="[email protected]" />
</FloatingLabel>
<FloatingLabel controlId="floatingPassword" label="Имя" style={{color:'#F0A650'}}>
<Form.Control type="text" placeholder="Password" />
</FloatingLabel>
<FloatingLabel controlId="floatingPassword" label="Отчество" style={{color:'#F0A650', marginTop:'15px'}}>
<Form.Control type="text" placeholder="Password" />
</FloatingLabel>
<Form.Group controlId="formFile" className="mb-3" style={{color:'#F0A650', marginTop:'10px'}}>
<Form.Label>Аватар пользователя</Form.Label>
<Form.Control type="file" />
</Form.Group>
<button className='btn-auth' style={{marginTop:'15px'}}>Зарегистрироваться</button>
</Modal.Body>
</Modal>
</div>
)
}
}
//store.ts
import { makeAutoObservable } from "mobx";
import { User } from "../model/User";
import AuthService from "../service/AuthService";
import api from "../http";
interface Credentials {
email: string;
password: string;
}
export default class Store {
user: Credentials = { email: '', password: '' };
error?: string[] = [];
isAuth = false;
isLoading = false;
constructor() {
makeAutoObservable(this);
}
setAuth(bool: boolean) {
this.isAuth = bool;
}
setUser(user: Credentials) {
this.user = user;
}
setLoading(bool: boolean) {
this.isLoading = bool;
}
setError(error?: string[]) {
this.error = error;
}
async registration(surname: string, name: string, lastname: string, email: string, password: string, color: string) {
try {
this.setError([]);
const { data } = await AuthService.registration(surname, name, lastname, email, password, color);
localStorage.setItem('token', data.accessToken);
this.setAuth(true);
const credentials: Credentials = { email: data.user.email, password: data.user.password };
this.setUser(credentials);
return data;
} catch (e) {
console.log(e);
let error: any = e;
this.setError(error.response.data.message);
}
}
}
код, где упоминается Header.tsx:
import React, { Component } from 'react';
import Header from '../components/Header';
import '../style/Home.scss';
import MyCarousel from '../components/Carousel';
import Store from '../store/store';
const store = new Store();
export default class Home extends Component {
render() {
return (
<div className="home">
<div className="home__cont">
<Header/>
<MyCarousel />
</div>
</div>
);
}
}
//app.tsx
import React from 'react';
import './App.css';
import { Route, Routes } from 'react-router-dom';
import Home from './page/Home';
import { Reg } from './components/Reg';
function App() {
return (
<Routes>
<Route path='/' element={<Home/>}/>
</Routes>
);
}
export default App;
//index.tsx
// index.ts
import React, { createContext } from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import Store from './store/store';
import { BrowserRouter } from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
interface State {
store: Store
}
const store = new Store()
export const Context = createContext<State>({
store,
})
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<BrowserRouter>
<React.StrictMode>
<Context.Provider value={{
store
}}>
<App />
</Context.Provider>
</React.StrictMode>
</BrowserRouter>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();