繁体   English   中英

将 componentDidUpdate(prevProps) 重写为带有 redux 的钩子

[英]rewrite componentDidUpdate(prevProps) into a hook with redux

我想将此生命周期方法重写为一个钩子,但它没有按预期工作。 当组件didmount时,如果用户id存在于本地存储中,则用户已连接并且他的名字显示在导航栏中。 当他断开连接并重新连接时,他的名字会显示在导航栏中。 所以我试图用钩子转换这个类组件,当用户名改变时,导航栏中没有显示任何内容,所以我必须刷新页面,这样他的名字就会显示出来

真正的问题是 componentDidUpdate 我怎样才能得到和比较 prevProps 和钩子

类组件

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;

如何获得之前的道具或状态?

基本上创建一个自定义钩子来缓存一个值:

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>
  )
};

仅供参考:您可能需要稍微重构一下代码,以便在仅在挂载时运行的效果挂钩中从本地存储中获取数据。 如果我正确理解您的应用程序流程,它将如下所示:

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>
  )
};

现在我解决了,我做了这个


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>
    )
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM