我正在使用套接字中的useEffect Hook获取数据。每次获得响应时,都会重新渲染一个特定的组件,但是我不会将任何套接字数据传递给该组件。
代码:
const App = () => {
const isMounted = React.useRef(false);
const [getSocketData, setSocketData] = useState([]);
useEffect(() => {
console.log('[App.js] Mounted!');
isMounted.current = true;
const socket = socketIOClient(process.env.REACT_APP_BOARD);
socket.on('ServersInfo', (data) => {
if (isMounted.current) {
setSocketData([...data]);
}
});
socket.on('connect_error', () => {
if (isMounted.current) {
setSocketData([]);
}
console.log('Connection error!');
});
return (() => {
isMounted.current = false;
socket.disconnect();
console.log('[App.js] unmounted');
});
}, []);
const routes = (
<Switch>
<Route path={['/', '/users/:id']} exact component={() => <MainPage axiosInstance={axiosInstance} />} />
<Route path='/servers' render={(spProps) => <ServerPing {...spProps} />} />
<Route render={(nfProps) => <NotFoundComponent {...nfProps} />} />
{/* <Redirect to='/' /> */}
</Switch>
);
return (
<div className="App">
<Layout>
<Suspense fallback={<p>Loading...</p>}>
{routes}
</Suspense>
</Layout>
</div>
);
};
export default App;
我的组件是什么样的: -App.js -布局(不重新呈现)(有3个子级)-MainPage(无限重新呈现),ServerPing(不重新呈现),NotFoundComponent(不重新呈现)
问题是:为什么MainPage组件无限渲染? 我的意思是,当套接字数据获取异常行为时,MainPage Component及其子级将再次卸载并安装。
MainPageComponent:
const MainPage = ({ axiosInstance, ...props }) => {
const isMounted = React.useRef(false);
const [loadingPage, setLoadingPage] = useState(true);
const [usernames, setUsernames] = useState([]);
const [currentDay] = useState(new Date().getDay());
useEffect(() => {
isMounted.current = true;
console.log('[MainPage.js] Mounted!');
getUsers();
return () => {
console.log('[MainPage.js] Unmounted!');
isMounted.current = false;
};
}, []);
const getUsers = async () => {
try {
const res = await axiosInstance.get('/users');
const newData = await res.data;
const newArray = [];
newData.map(user => (
newArray.push({id: user._id, flag: user.flag, text: user.name, value: user.name.toLowerCase()})
));
if (isMounted.current) {
setUsernames(newArray);
setLoadingPage(false);
}
} catch {
if (isMounted.current) {
setLoadingPage(false);
}
}
};
return...
答案 0 :(得分:1)
问题是您在component
上使用render
道具,而不是render the MainPage
道具,如果有回调传递给组件道具
下面的代码应解决此问题
<Route
path={['/', '/users/:id']}
exact
render={(props) => <MainPage {...props} axiosInstance={axiosInstance} />}
/>
react-router-dom文档
当您使用组件(而不是下面的渲染器或子代)时, 路由器使用
React.createElement
从 给定的组件。也就是说,如果您向 组件属性,您将在每个渲染中创建一个新组件。这个 导致现有组件的卸载和新组件的安装 安装而不只是更新现有组件。使用时 用于内联渲染的内联函数,请使用render
或children
道具(如下)。