我想将此生命周期方法重写为一个钩子,但无法按预期工作。 挂载组件后,如果本地存储中存在用户ID,则表示该用户已连接,并且其名称显示在导航栏中。当他断开连接并重新连接时,他的名字将显示在导航栏中。 因此,我尝试使用钩子转换此类Component,当用户名更改时,导航栏中不显示任何内容,因此我必须刷新页面并以这种方式显示他的名字
真正的问题是componentDidUpdate 我如何获得和比较带有钩子的prevProps
类Component
const mapStateToProps = state => ({
...state.authReducer
}
);
const mapDispatchToProps = {
userSetId,
userProfilFetch,
userLogout
};
class App extends React.Component {
componentDidMount() {
const userId = window.localStorage.getItem("userId");
const {userSetId} = this.props;
if (userId) {
userSetId(userId)
}
}
componentDidUpdate(prevProps, prevState, snapshot) {
const {userId, userProfilFetch, userData} = this.props; //from redux store
if(prevProps.userId !== userId && userId !== null && userData === null){
userProfilFetch(userId);
}
}
render() {
return (
<div>
<Router>
<Routes/>
</Router>
</div>
);
}
}
export default connect(mapStateToProps,mapDispatchToProps)(App);
带钩子
const App = (props) => {
const dispatch = useDispatch();
const userData = useSelector(state => state.authReducer[props.userData]);
const userId = window.localStorage.getItem("userId");
useEffect(()=> {
if(!userId){
dispatch(userSetId(userId))
dispatch(userProfilFetch(userId))
}
}, [userData, userId, dispatch])
return(
<Router>
<Routes/>
</Router>
)
};
export default App;
答案 0 :(得分:2)
How to get the previous props or state?
基本上创建一个自定义钩子来缓存值:
const usePrevious = value => {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
用法:
const App = (props) => {
const dispatch = useDispatch();
const userData = useSelector(state => state.authReducer[props.userData]);
const userId = window.localStorage.getItem("userId");
// get previous id and cache current id
const prevUserId = usePrevious(userId);
useEffect(()=> {
if(!userId){
dispatch(userSetId(userId))
dispatch(userProfileFetch(userId))
}
// do comparison with previous and current id value
if (prevUserId !== userId) {
dispatch(userProfileFetch(userId));
}
}, [userData, userId, prevUserId, dispatch])
return(
<Router>
<Routes/>
</Router>
)
};
FYI:您可能需要对代码进行一些重构,以便在仅在安装时运行的效果挂钩中进行从本地存储的提取。如果我正确了解您的应用程序流程,它将看起来像这样:
const App = (props) => {
const dispatch = useDispatch();
const { userId } = useSelector(state => state.authReducer[props.userData]);
useEffect(() => {
const userId = window.localStorage.getItem("userId");
userId && dispatch(userSetId(userId));
}, []);
// get previous id and cache current id
const prevUserId = usePrevious(userId);
useEffect(()=> {
if(!userId){
dispatch(userSetId(userId))
dispatch(userProfileFetch(userId))
}
// do comparison with previous and current id value
if (prevUserId !== userId) {
dispatch(userProfileFetch(userId));
}
}, [userId, prevUserId, dispatch])
return(
<Router>
<Routes/>
</Router>
)
};
答案 1 :(得分:0)
现在我解决了,我做了
const App = props => {
const userId = window.localStorage.getItem("userId");
const dispatch = useDispatch();
const userData = useSelector(state=> state.authReducer[props.userData]);
const isAuthenticated = useSelector(state=> state.authReducer.isAuthenticated);
useEffect(()=> {
if(userId){
dispatch(userSetId(userId))
dispatch(userProfilFetch(userId))
}
}, [userId])
return(
<div>
<Router>
<Routes/>
</Router>
</div>
)
};