問題の説明
React の状態管理ツールとして mobx を使用している場合、非同期でデータを取得した後、ページがデータを取得してレンダリングするにもかかわらず、コンソールで警告が表示されます。
コードは以下のように表示されます。
ChannelStore.js
import { makeAutoObservable } from 'mobx'
import axios from 'axios'
class ChannelStore {
channelList = []
constructor() {
makeAutoObservable(this)
}
setChannelList = async () => {
const res = await axios.get('http://geek.itheima.net/v1_0/channels')
this.channelList = res.data.data.channels
}
}
const channelStore = new ChannelStore()
export default channelStore
アプリ.js
import './App.css'
import {useEffect} from 'react'
import channelStore from './store/ChannelStore'
import {observer} from 'mobx-react-lite'
function App() {
useEffect(() => {
channelStore.setChannelList().then()
}, [])
return (
<div className="App">
app
{channelStore.channelList.map(item => <div key={item.id}>{item.name}</div>)}
</div>
)
}
export default observer(App)
理由
変換でエラーが報告された場合: [MOBX] 厳密モードが有効になっているため、アクションを使用せずに値を変更 (監視) することはできません。
人間の言葉: 非同期関数はデータを直接変更できません。
解決
setChannelList メソッドは非同期であるため、runInAction で呼び出すか、個別に設定する必要があります。
import { makeAutoObservable, runInAction } from 'mobx'
import axios from 'axios'
class ChannelStore {
channelList = []
constructor() {
makeAutoObservable(this)
}
setChannelList = async () => {
const res = await axios.get('http://geek.itheima.net/v1_0/channels')
// 用runInAction包裹,可以让mobx知道这是一个action,可以修改state
runInAction(() => {
this.channelList = res.data.data.channels
})
// 或者调用其他方法来修改state
// this.setChannelList2(res.data.data.channels)
}
// 或者调用其他方法来修改state
// setChannelList2 = (list) => {
// this.channelList = list
// }
}
const channelStore = new ChannelStore()
export default channelStore