[英]how could i use useEffect to replace componentDidMount?
I would like to use useEffect()
to instead of componentWillMount()
, but I found the hook can not use in class components, so I change the code as Function component, but it will get more error for the whole component, all code with this.xxx are getting an error, how could I edit below code to make it work?我想使用
useEffect()
来代替componentWillMount()
,但我发现钩子不能在类组件中使用,所以我将代码更改为 Function 组件,但它会为整个组件带来更多错误,所有代码都带有this.xxx 出现错误,我如何编辑下面的代码以使其正常工作? Please help me.请帮我。 Below code is working fine with
componentWillMount()
.下面的代码与
componentWillMount()
一起工作正常。
import React, { Component } from 'react';
import './index.less';
import { formateDate } from '../../utils/dateUtils';
import memoryUtils from '../../utils/memoryUtils';
import { reqWeather } from '../../api/index';
import { withRouter } from 'react-router-dom';
import menuList from '../../config/menuConfig';
class Header extends Component {
state = {
currentTime: formateDate(Date.now()),
dayPictureUrl: '',
weather: '',
};
getTime = () => {
setInterval(() => {
const currentTime = formateDate(Date.now());
this.setState({ currentTime });
}, 1000);
};
getWeather = async () => {
const { dayPictureUrl, weather } = await reqWeather('Auckland');
this.setState({ dayPictureUrl, weather });
};
getTitle = (props) => {
const path = this.props.location.pathname;
let title;
menuList.forEach(item => {
if (item.key === path) {
title = item.title;
} else if (item.children) {
const cItem = item.children.find(cItem => cItem.key === path);
if (cItem) {
title = cItem.title;
}
}
});
return title;
};
componentDidMount() {
this.getTime();
this.getWeather();
}
render() {
const { currentTime, dayPictureUrl, weather } = this.state;
const username = memoryUtils.user.username;
const title = this.getTitle();
return (
<div className="header">
<div className="header-top">
<span>Welcome, {username}</span>
<a href>logout</a>
</div>
<div className="header-bottom">
<div className="header-bottom-left">{title}</div>
<div className="header-bottom-right">
<span>{currentTime}</span>
<img src={dayPictureUrl} alt="weather" />
<span>{weather}</span>
</div>
</div>
</div>
);
}
}
export default withRouter(Header)
I've converted from react classes to react hooks I hope it help, I haven't tested because I don't have the external files that you have but I hope it helps otherwise just comment on this solution ;)我已经从反应类转换为反应钩子我希望它有帮助,我没有测试,因为我没有你拥有的外部文件,但我希望它有帮助,否则只是对这个解决方案发表评论;)
import React, { useState, useEffect } from 'react';
import './index.less';
import { formateDate } from '../../utils/dateUtils';
import memoryUtils from '../../utils/memoryUtils';
import { reqWeather } from '../../api/index';
import { withRouter, useLocation } from 'react-router-dom';
import menuList from '../../config/menuConfig';
function Header(){
const [currentTime, setCurrentTime] = useState(formateDate(Date.now()))
const [dayPictureUrl, setDayPictureUrl] = useState('')
const [weather, setWeather] = useState('')
const location = useLocation();
const path = location.pathname;
useEffect(() => {
getTime();
getWeather();
},[]);
const getTime = () => {
setInterval(() => {
const currentTime = formateDate(Date.now());
setCurrentTime(currentTime)
}, 1000);
};
const getWeather = async () => {
const { dayPictureUrl, weather } = await reqWeather('Auckland');
setDayPictureUrl(dayPictureUrl)
setWeather(weather)
};
const getTitle = (props) => {
let title;
menuList.forEach(item => {
if (item.key === path) {
title = item.title;
} else if (item.children) {
const cItem = item.children.find(cItem => cItem.key === path);
if (cItem) {
title = cItem.title;
}
}
});
return title;
};
const username = memoryUtils.user.username;
const title = getTitle();
return (<div className="header">
<div className="header-top">
<span>Welcome, {username}</span>
<a href>logout</a>
</div>
<div className="header-bottom">
<div className="header-bottom-left">{title}</div>
<div className="header-bottom-right">
<span>{currentTime}</span>
<img src={dayPictureUrl} alt="weather" />
<span>{weather}</span>
</div>
</div>
</div> )
}
export default Header
Here's my go at converting the function to using hooks.这是我将函数转换为使用钩子的方法。
One of the best things about hooks is that they can all be called as many times as you like, which allows us to separate the concerns of a component into logical blocks.关于钩子的最好的事情之一是它们都可以根据需要多次调用,这允许我们将组件的关注点分离为逻辑块。
useEffect
shouldn't be considered a direct replacement for componentDidMount as it works differently. useEffect
不应被视为 componentDidMount 的直接替代品,因为它的工作方式不同。 The closest would actually be useLayoutEffect
because of the timing of it matches componentDidMount
and componentdDidUpdate
.最接近的实际上是
useLayoutEffect
因为它匹配componentDidMount
和componentdDidUpdate
。 More detail on the difference between the two: useEffect vs useLayoutEffect .关于两者区别的更多细节: useEffect 与 useLayoutEffect 。 Although you should in general use
useEffect
primarily.虽然您通常应该主要使用
useEffect
。
Getting used to hooks requires a bit of a shift in how you think of components, but in my opinion, it's worth the effort to switch!习惯 hooks 需要稍微改变您对组件的看法,但在我看来,转换的努力是值得的!
import React, {useEffect, useMemo, useState} from 'react';
import './index.less';
import { formateDate } from '../../utils/dateUtils';
import memoryUtils from '../../utils/memoryUtils';
import { reqWeather } from '../../api/index';
import { useLocation } from 'react-router-dom';
import menuList from '../../config/menuConfig';
export default function Header (props){
const [currentTime, setCurrentTime] = useState(formateDate(Date.now()));
useEffect(()=>{
const intervalId = setInterval(()=>{
setCurrentTime(formateDate(Date.now()));
},1000)
// Make sure to cleanup your effects!
return ()=>{clearInterval(intervalId)}
},[])
const [dayPictureUrl, setDayPictureUrl] = useState('');
const [weather, setWeather] = useState('');
useEffect(() => {
const getWeather = async () => {
const { dayPictureUrl, weather } = await reqWeather('auckland');
setDayPictureUrl(dayPictureUrl);
setWeather(weather);
};
// Assuming that we want to have the weather dynamically based on a passed in prop (i.e. props.city), or a state.
getWeather();
}, []);
// useLocation gets the location via a hook from react router dom
const location = useLocation();
const title = useMemo(()=>{
// useMemo as this can be an expensive calculation depending on the length of menuList
// menuList is always a constant value, so it won't change
const path = location.pathname;
let title;
menuList.forEach(item => {
if (item.key === path) {
title = item.title;
} else if (item.children) {
const cItem = item.children.find(cItem => cItem.key === path);
if (cItem) {
title = cItem.title;
}
}
});
return title;
},[location.pathname])
const username = memoryUtils.user.username;
return (
<div className="header">
<div className="header-top">
<span>Welcome, {username}</span>
<a href>logout</a>
</div>
<div className="header-bottom">
<div className="header-bottom-left">{title}</div>
<div className="header-bottom-right">
<span>{currentTime}</span>
<img src={dayPictureUrl} alt="weather" />
<span>{weather}</span>
</div>
</div>
</div>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.