You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从jQuery迁移至ReactJS遇阻:DOM访问与请求事件处理咨询

Migrating jQuery WebForms Code to ReactJS: Answers to Your Key Questions

Let's break down your two main questions with practical, React-specific solutions that align with your existing code structure:


1. Accessing Master Page DOM Elements in JSX

Since the HyperlinkNavigation element lives outside your React component (in the Master Page), you can't use React refs directly for it. Instead, you'll use React's useEffect hook to safely access the DOM after your component mounts (ensuring the element exists in the DOM tree).

Example Implementation:

import React, { useEffect } from 'react';

function SessionManager() {
  useEffect(() => {
    // Get reference to the master page navigation button
    const navButton = document.getElementById("HyperlinkNavigation");
    
    if (navButton) {
      // Apply the same class styling as your original jQuery code
      navButton.className = "navigation__button navigation__button--back";
      
      // Attach the click handler
      const handleNavClick = () => {
        navButton.href = "applications.aspx";
      };
      navButton.addEventListener('click', handleNavClick);
      
      // Cleanup: Remove event listener when component unmounts
      return () => {
        navButton.removeEventListener('click', handleNavClick);
      };
    }
  }, []); // Empty dependency array ensures this runs once on mount

  return (
    <div className="sessionmanager">
      {/* Your React UI content here */}
    </div>
  );
}

export default SessionManager;

Key Notes:

  • Always add a check for navButton to avoid errors if the element isn't loaded yet.
  • Use the cleanup function in useEffect to remove event listeners—this prevents memory leaks when your component unmounts.

2. Replacing beginRequest/endRequest Logic in React

Your original code uses WebForms' PageRequestManager to preserve scroll position during partial postbacks. There are two approaches depending on whether you're still using WebForms partial postbacks or migrating to React-native async requests:

Option 1: Keep Using WebForms Partial Postbacks

You can still listen to the PageRequestManager events from within your React component. Just make sure to clean up the event listeners when the component unmounts:

import React, { useEffect } from 'react';

function SessionManager() {
  useEffect(() => {
    const prm = window.Sys.WebForms.PageRequestManager.getInstance();
    let xPos, yPos;
    const scroolBarPlaceHolder = '<%= ClientID %>'; // Keep your existing ASP.NET variable

    const beginRequestHandler = (sender, args) => {
      // Capture scroll position before postback
      const element = document.getElementById(scroolBarPlaceHolder);
      if (element) {
        xPos = element.scrollLeft;
        yPos = element.scrollTop;
      }
    };

    const endRequestHandler = (sender, args) => {
      // Restore scroll position after postback
      const element = document.getElementById(scroolBarPlaceHolder);
      if (element) {
        element.scrollLeft = xPos;
        element.scrollTop = yPos;
      }
    };

    // Register event listeners
    prm.add_beginRequest(beginRequestHandler);
    prm.add_endRequest(endRequestHandler);

    // Cleanup: Remove listeners on unmount
    return () => {
      prm.remove_beginRequest(beginRequestHandler);
      prm.remove_endRequest(endRequestHandler);
    };
  }, []);

  // ... rest of your component code
}

If you're moving away from WebForms postbacks to React-friendly async calls (like Axios), use Axios interceptors to replicate the scroll position logic:

import React, { useEffect, useState } from 'react';
import axios from 'axios';

function SessionManager() {
  const [scrollPos, setScrollPos] = useState({ x: 0, y: 0 });
  const scroolBarPlaceHolder = '<%= ClientID %>';

  useEffect(() => {
    // Add Axios request interceptor (runs before request starts)
    const requestInterceptor = axios.interceptors.request.use(config => {
      const element = document.getElementById(scroolBarPlaceHolder);
      if (element) {
        setScrollPos({
          x: element.scrollLeft,
          y: element.scrollTop
        });
      }
      return config;
    });

    // Add Axios response interceptor (runs after request completes)
    const responseInterceptor = axios.interceptors.response.use(response => {
      const element = document.getElementById(scroolBarPlaceHolder);
      if (element) {
        element.scrollLeft = scrollPos.x;
        element.scrollTop = scrollPos.y;
      }
      return response;
    });

    // Cleanup: Remove interceptors when component unmounts
    return () => {
      axios.interceptors.request.eject(requestInterceptor);
      axios.interceptors.response.eject(responseInterceptor);
    };
  }, [scrollPos]);

  // ... rest of your component code
}

Bonus: Migrating User Activity Tracker & Ping Logic

Here's how to port your activity tracking and ping timer to React:

import React, { useEffect, useState, useRef } from 'react';

function SessionManager() {
  const [userActivity, setUserActivity] = useState(true);
  const socketID = 'your-socket-id'; // Replace with your actual socket ID logic
  const pingTimerRef = useRef(null);

  useEffect(() => {
    // Track user activity
    const handleActivity = () => setUserActivity(true);
    
    ['mousedown', 'touchstart', 'mousewheel', 'keydown'].forEach(event => {
      document.addEventListener(event, handleActivity);
    });

    // Set up ping interval
    pingTimerRef.current = setInterval(() => {
      makePing(socketID, userActivity);
      setUserActivity(false); // Reset activity flag after ping
    }, 5000);

    // Cleanup: Remove event listeners and clear timer
    return () => {
      ['mousedown', 'touchstart', 'mousewheel', 'keydown'].forEach(event => {
        document.removeEventListener(event, handleActivity);
      });
      clearInterval(pingTimerRef.current);
    };
  }, [socketID, userActivity]);

  // Define your makePing function
  const makePing = (socketId, activity) => {
    // Your existing ping logic here (e.g., Axios call to server)
  };

  return (
    <div className="sessionmanager">
      {/* Your React UI content */}
    </div>
  );
}

内容的提问来源于stack exchange,提问作者hightides1973

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:40:48