Reputation: 85
Have been following a few tutorials on youtube and have pretty much never seen anyone explicitly define an action that mutates the state they just throw in into the store. I have been doing the same and while it works a 100% it throws a warning on react native. Just wondering how you could define that something is an action and maybe if someone has a good way to separate the actions into a different file. Here is my store.
export function createCurrencyStore() {
return {
currencies: [
'AED',
'ARS',
'AUD',
],
selectedCurrencyFrom: 'USD',
selectedCurrencyTo: 'EUR',
loading: false,
error: null,
exchangeRate: null,
amount: 1,
fromFilterString: '',
fromFilteredCurrencies: [],
toFilterString: '',
toFilteredCurrencies: [],
setSelectedCurrencyFrom(currency) {
this.selectedCurrencyFrom = currency
},
setSelectedCurrencyTo(currency) {
this.selectedCurrencyTo = currency
},
async getExchangeRate() {
const conn = await fetch(
`https://api.exchangerate-api.com/v4/latest/${this.selectedCurrencyFrom}`
)
const res = await conn.json()
console.log(res)
this.exchangeRate = res.rates[this.selectedCurrencyTo]
},
setFromFilters(string) {
this.fromFilterString = string
if (this.fromFilterString !== '') {
this.fromFilteredCurrencies = this.currencies.filter((currency) =>
currency.toLowerCase().includes(string.toLowerCase())
)
} else {
this.fromFilteredCurrencies = []
}
},
setToFilters(string) {
this.toFilterString = string
if (this.toFilterString !== '') {
this.toFilteredCurrencies = this.currencies.filter((currency) =>
currency.toLowerCase().includes(string.toLowerCase())
)
} else {
this.toFilteredCurrencies = []
}
},
}
}
Upvotes: 0
Views: 1125
Reputation: 18486
have pretty much never seen anyone explicitly define an action
Well, this is weird because it is a very common thing to only mutate state through actions to avoid unexpected mutations. In MobX6 actions are enforced by default, but you can disable warnings with configure
method:
import { configure } from "mobx"
configure({
enforceActions: "never",
})
a good way to separate the actions into a different file
You don't really need to do it, unless it's a very specific case and you need to somehow reuse actions or something like that. Usually you keep actions and the state they modify together.
I am not quite sure what you are doing with result of createCurrencyStore
, are you passing it to observable
? Anyway, the best way to create stores in MobX6 is to use makeAutoObservable
(or makeObservable
if you need some fine tuning). So if you are not using classes then it will look like that:
import { makeAutoObservable } from "mobx"
function createDoubler(value) {
return makeAutoObservable({
value,
get double() {
return this.value * 2
},
increment() {
this.value++
}
})
}
That way every getter will become computed
, every method will become action
and all other values will be observable
s basically.
More info in the docs: https://mobx.js.org/observable-state.html
UPDATE:
Since your getExchangeRate
function is async then you need to use runInAction
inside, or handle result in separate action, or use some other way of handling async actions:
import { runInAction} from "mobx"
async getExchangeRate() {
const conn = await fetch(
`https://api.exchangerate-api.com/v4/latest/${this.selectedCurrencyFrom}`
)
const res = await conn.json()
runInAction(() => {
this.exchangeRate = res.rates[this.selectedCurrencyTo]
})
// or do it in separate function
this.handleExchangeRate(res.rates[this.selectedCurrencyTo])
},
More about async actions: https://mobx.js.org/actions.html#asynchronous-actions
Upvotes: 1