Parent : [[INDEX-WEB-UIUX]]
FiveM - React NUI Banking : state management, hash generation, currency format
Problème
Les UI FiveM traditionnelles utilisent du HTML vanilla avec jQuery. Une UI bancaire complexe (transferts, historique, cartes) nécessite un framework frontend moderne pour le state management et la réactivité.
Solution
Application React dans NUI FiveM avec hooks useState/useEffect, génération de numéros de carte basée sur hash, formatage currency, et communication via window.invokeNative / fetchNui.
// Génération de numéro de carte basée sur un seed (identifiant joueur)
const generateCardNumber = (seed = '') => {
let hash = 0;
for (let i = 0; i < seed.length; i++) {
const char = seed.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
const num = Math.abs(hash) % 10000;
return num.toString().padStart(4, '0');
};
// Formatage currency
const formatCurrency = (amount, currency = 'USD') => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency
}).format(amount);
};
// Fetch NUI helper
const fetchNui = async (eventName, data) => {
const resourceName = window.GetParentResourceName?.() || 'nui-frame';
const resp = await fetch(`https://${resourceName}/${eventName}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
return await resp.json();
};
// React hook pour les transactions
const useTransactions = () => {
const [transactions, setTransactions] = useState([]);
useEffect(() => {
fetchNui('getTransactions', {}).then(setTransactions);
const interval = setInterval(() => {
fetchNui('getTransactions', {}).then(setTransactions);
}, 30000);
return () => clearInterval(interval);
}, []);
return transactions;
};
Pourquoi
- React offre une UI réactive sans DOM manipulation manuelle
- Le hash de carte garantit la cohérence visuelle par joueur
fetchNuiest le standard moderne pour la communication NUI ↔ Lua
Quand l'utiliser
- UI complexes avec état (inventaire, banking, téléphone, MDT)
- Interfaces nécessitant listes dynamiques, filtres, pagination
Quand NE PAS l'utiliser
- UI simples (notification toast, progress bar) →
ox_libsuffit - Si le bundle React dépasse 500KB et cause des temps de chargement longs
Exemples
Correct
// React component avec NUI event listeners
const BankingApp = () => {
const [visible, setVisible] = useState(false);
const [balance, setBalance] = useState(0);
useEffect(() => {
window.addEventListener('message', (event) => {
if (event.data.type === 'openBank') {
setVisible(true);
setBalance(event.data.balance);
}
if (event.data.type === 'closeBank') {
setVisible(false);
}
});
}, []);
const handleTransfer = async (targetId, amount) => {
const result = await fetchNui('transferMoney', { targetId, amount });
if (result.success) {
setBalance(prev => prev - amount);
}
};
return visible ? <BankingUI balance={balance} onTransfer={handleTransfer} /> : null;
};
Incorrect
// Manipulation DOM directe dans NUI (buggy, non-réactive)
document.getElementById('balance').innerText = '$' + data.balance;
document.getElementById('transfer-btn').onclick = function() {
fetch('https://resource/transfer', { method: 'POST' }); // Pas de async/await
};
Références
- omes_banking/nui/script.js
- REF-001 (CFX NUI documentation)