Use mobx and react get an error: Too many re-renders. React limits the number of renders to prevent an infinite loop
Use mobx and react get an error: Too many re-renders. React limits the number of renders to prevent an infinite loop
在我看来,我想使用mobx来保存一个名为mask的状态,当我使用axios时,这个状态将为真,当我完成调用时,这个状态将为假,下面是我的代码
store.tsx
import { makeAutoObservable, runInAction } from 'mobx';
import axios from 'axios';
class Store {
isHeaderShow = false;
isTabBarShow = false;
isShowingMovies = [];
isShowingMovieIds = [];
willShowingMovies = [];
willShowingMovieIds = [];
isLoading = false;
constructor() {
makeAutoObservable(this);
}
getShowingMovies = async () => {
if (this.isShowingMovies.length === 0) {
this.isLoading = true;
let res = await axios.get(`http://localhost:3000/movie/ajax/movieOnInfoList`).then((res) => {
return res.data;
this.isLoading = false;
})
runInAction(() => {
this.isShowingMovies = res.movieList;
this.isShowingMovieIds = res.movieIds;
})
}
}
}
const store = new Store();
export default store
mask.tsx
import React, { useState, FC } from 'react'
import { Mask } from 'antd-mobile'
import store from '../../mobx/store'
import { observer } from 'mobx-react';
const SimpleMask: FC = () => {
const [visible, setVisible] = useState(false)
setVisible(store.isLoading);
return (
<>
<Mask visible={visible} />
</>
)
}
export default observer(SimpleMask)
App.tsx
import React from 'react';
import './App.css';
import Header from './component/header'
import Footer from './component/footer'
import Mask from './component/mark'
function App() {
return (
<div className="container">
<div className='header'>
<Header />
</div>
<div className='main'>This is main</div>
<div className='footer'>
<Footer />
</div>
<Mask/>
</div>
);
}
export default App;
package.json
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.4.1",
"@types/node": "^16.11.26",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.13",
"antd-mobile": "^5.4.0",
"axios": "^0.26.0",
"mobx": "^6.4.2",
"mobx-react": "^7.3.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"typescript": "^4.6.2",
"web-vitals": "^2.1.4"
},
错误如下
error info
你们能给我一些建议吗?我是第一次使用 react 和 mobx,想改进。
非常感谢!
您直接在 Mask
组件中调用 setVisible
,这会导致 re-render,这会导致再次调用 setVisible
,无限循环继续。
您可以做到仅在 store.isLoading
在 useEffect
的帮助下实际发生变化时才更新状态:
const SimpleMask: FC = () => {
const [visible, setVisible] = useState(false)
useEffect(() => {
setVisible(store.isLoading)
}, [store.isLoading])
return (
<Mask visible={visible} />
)
}
或者您可以完全跳过 useState
,直接使用您的商店:
const SimpleMask: FC = () => {
return (
<Mask visible={store.isLoading} />
)
}
在我看来,我想使用mobx来保存一个名为mask的状态,当我使用axios时,这个状态将为真,当我完成调用时,这个状态将为假,下面是我的代码
store.tsx
import { makeAutoObservable, runInAction } from 'mobx';
import axios from 'axios';
class Store {
isHeaderShow = false;
isTabBarShow = false;
isShowingMovies = [];
isShowingMovieIds = [];
willShowingMovies = [];
willShowingMovieIds = [];
isLoading = false;
constructor() {
makeAutoObservable(this);
}
getShowingMovies = async () => {
if (this.isShowingMovies.length === 0) {
this.isLoading = true;
let res = await axios.get(`http://localhost:3000/movie/ajax/movieOnInfoList`).then((res) => {
return res.data;
this.isLoading = false;
})
runInAction(() => {
this.isShowingMovies = res.movieList;
this.isShowingMovieIds = res.movieIds;
})
}
}
}
const store = new Store();
export default store
mask.tsx
import React, { useState, FC } from 'react'
import { Mask } from 'antd-mobile'
import store from '../../mobx/store'
import { observer } from 'mobx-react';
const SimpleMask: FC = () => {
const [visible, setVisible] = useState(false)
setVisible(store.isLoading);
return (
<>
<Mask visible={visible} />
</>
)
}
export default observer(SimpleMask)
App.tsx
import React from 'react';
import './App.css';
import Header from './component/header'
import Footer from './component/footer'
import Mask from './component/mark'
function App() {
return (
<div className="container">
<div className='header'>
<Header />
</div>
<div className='main'>This is main</div>
<div className='footer'>
<Footer />
</div>
<Mask/>
</div>
);
}
export default App;
package.json
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.4.1",
"@types/node": "^16.11.26",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.13",
"antd-mobile": "^5.4.0",
"axios": "^0.26.0",
"mobx": "^6.4.2",
"mobx-react": "^7.3.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"typescript": "^4.6.2",
"web-vitals": "^2.1.4"
},
错误如下 error info
你们能给我一些建议吗?我是第一次使用 react 和 mobx,想改进。 非常感谢!
您直接在 Mask
组件中调用 setVisible
,这会导致 re-render,这会导致再次调用 setVisible
,无限循环继续。
您可以做到仅在 store.isLoading
在 useEffect
的帮助下实际发生变化时才更新状态:
const SimpleMask: FC = () => {
const [visible, setVisible] = useState(false)
useEffect(() => {
setVisible(store.isLoading)
}, [store.isLoading])
return (
<Mask visible={visible} />
)
}
或者您可以完全跳过 useState
,直接使用您的商店:
const SimpleMask: FC = () => {
return (
<Mask visible={store.isLoading} />
)
}