import { Text, TextInput, View, Button } from 'react-native';
import { useState } from 'react';
export default function App() {
function handleLogin() {
}
return (
<View style={{ flex: 1, padding: 24, gap: 24 }}>
<TextInput placeholder="Username" style={{ borderWidth: 1 }} />
<TextInput placeholder="Password" style={{ borderWidth: 1 }} secureTextEntry />
<Button title="Login" onPress={ handleLogin }/>
</View>
);
}
Pour encapsuler les données et comportements d'une entité de l'application, les classes permettent d'exploiter les concepts orienté-objet en JavaScript.
class UserCredentials {
constructor({username, password}) {
this.username = username
this.password = password
}
}
class User {
#id;
constructor({ id, username }) {
this.#id = id
this.username = username
}
get id() {
return this.#id
}
toJSON() {
return {
id: this.#id,
...this
}
}
}
Pour encapsuler la manipulation des données de l'application, ex: CRUDL, en utilisant les modules, on obtient automatiquement le comportement d'un singleton.
📚 Modules
class AuthService {
#currentUser = null // ATTENTION, à utiliser judicieusement
get currentUser() {
return this.#currentUser
}
async signUp(credentials) {
const response = await fetch("http://martha.jh.shawinigan.info/queries/insert-user/execute", {
method: 'POST',
body: JSON.stringify(credentials),
headers: {
'auth': 'ZGVtbzpSZWFjdE5hdGl2ZTIwMjQh'
}
}).then((r) => r.json())
if (response.success) {
this.#currentUser = new User({ id: response.lastInsertId, username: credentials.username })
}
return !!this.#currentUser
}
async logIn(credentials) {
const response = await fetch("http://martha.jh.shawinigan.info/queries/select-user-auth/execute", {
method: 'POST',
body: JSON.stringify(credentials),
headers: {
'auth': 'ZGVtbzpSZWFjdE5hdGl2ZTIwMjQh'
}
}).then((r) => r.json())
if (response.success && response.data.length == 1) {
const user = response.data[0]
this.#currentUser = new User({ id: user.id, username: user.username })
console.log(JSON.stringify(this.#currentUser))
} else {
this.#currentUser = null
}
return !!this.#currentUser
}
// ...
}
const service = new AuthService();
export default service;
import UserCredentials from './UserCredentials.model.js'
export default function App() {
const [credentials, setCredentials] = useState(new UserCredentials({username: '', password: ''}))
async function handleLogin() {
console.log({credentials})
}
return (
<TextInput
value={ credentials.username }
onChangeText={ text => setCredentials(new UserCredentials({...credentials, username: text })) }
/>
<TextInput
value={ credentials.password }
onChangeText={ text => setCredentials(new UserCredentials({...credentials, password: text })) }
/>
);
}
import auth from './Auth.service.js'
export default function App() {
const [credentials, setCredentials] = useState(new UserCredentials({username: '', password: ''}))
const [user, setUser] = useState()
async function handleLogin() {
console.log({credentials})
const success = await auth.logIn(credentials)
console.log({success, user: auth.currentUser})
setUser(auth.currentUser)
setCredentials(new UserCredentials({username: '', password: ''}))
}
function handleLogOut() {
auth.logOut()
setUser(auth.currentUser)
}
return (
<View style={{ flex: 1, padding: 24, gap: 24 }}>
{
user &&
<View>
<Text>{ JSON.stringify(user) }</Text>
<Button title="Log out" onPress={ handleLogOut }/>
</View>
}
</View>
);
}
src
├── App.js
├── components
│ ├── StyledButton.js
│ └── StyledTextInput.js
├── models
│ ├── User.js
│ └── UserCredentials.js
├── screens
│ ├── auth
│ │ ├── Login.js
│ │ └── Signup.js
│ ├── recipes
│ │ ├── RecipeItem.js
│ │ ├── Recipe.js
│ │ └── Recipes.js
│ └── Screen.js
└── services
└── Auth.js
src
├── App.js
├── auth
│ ├── Auth.service.js
│ ├── Login.js
│ ├── Signup.js
│ ├── UserCredentials.model.js
│ └── User.model.js
├── components
│ ├── Screen.js
│ ├── StyledButton.js
│ └── StyledTextInput.js
└── recipes
├── RecipeItem.js
├── Recipe.js
├── Recipe.model.js
└── Recipes.js