如何使用ReactJS处理服务器返回的HTML数据并实现组件交互?
Got it, let's break down how to implement this requirement where the ListInfo component shows full content by default, but switches to truncated content (with a "...") when the ShowMore component is present on the page.
Core Approach
We'll use React Context to share state between the two components—this way, ShowMore can control whether ListInfo truncates its content. This is a clean, React-native approach that avoids messy DOM queries.
Step 1: Create a Context to Manage Display State
First, set up a context to hold the truncation state and functions to update it:
import { createContext, useContext, useState } from 'react'; // Context to handle show/hide full content state const ShowMoreContext = createContext({ isTruncated: false, toggleTruncated: () => {}, setIsTruncated: () => {} }); // Provider component to wrap our components export const ShowMoreProvider = ({ children }) => { const [isTruncated, setIsTruncated] = useState(false); const toggleTruncated = () => { setIsTruncated(prev => !prev); }; return ( <ShowMoreContext.Provider value={{ isTruncated, toggleTruncated, setIsTruncated }}> {children} </ShowMoreContext.Provider> ); }; // Custom hook for easy access to the context export const useShowMore = () => useContext(ShowMoreContext);
Step 2: Update ListInfo Component
Modify ListInfo to use the context state and truncate content when needed. We'll first parse the HTML string from getUserInfo() to extract clean text items:
import { useShowMore } from './ShowMoreContext'; export const ListInfo = () => { const { isTruncated } = useShowMore(); const userInfoHtml = getUserInfo(); // Returns your HTML string // Parse the HTML to extract individual info items const parser = new DOMParser(); const doc = parser.parseFromString(userInfoHtml, 'text/html'); const infoItems = Array.from(doc.querySelectorAll('.info')).map(span => span.textContent.trim()); // Determine which items to display: truncate to first 2 if isTruncated is true const displayItems = isTruncated ? infoItems.slice(0, 2) : infoItems; return ( <div className="list-info-container"> {displayItems.map((item, idx) => ( <p key={idx} className="info-item">{item}</p> ))} {/* Show ellipsis only when truncated */} {isTruncated && <p className="ellipsis">...</p>} </div> ); };
Step 3: Build the ShowMore Component
Make ShowMore trigger the truncation state when it mounts, and add a button to toggle between truncated and full content:
import { useShowMore, useEffect } from 'react'; export const ShowMore = () => { const { isTruncated, toggleTruncated, setIsTruncated } = useShowMore(); // Automatically enable truncation when ShowMore is mounted useEffect(() => { setIsTruncated(true); }, [setIsTruncated]); return ( <button onClick={toggleTruncated} className="show-more-btn" > {isTruncated ? 'Show Full Info' : 'Show Less'} </button> ); };
Step 4: Use the Components
Without ShowMore: Just render
ListInfodirectly—it will show all content by default:const App = () => <ListInfo />;With ShowMore: Wrap both components in
ShowMoreProviderso they share the state:import { ShowMoreProvider } from './ShowMoreContext'; import { ListInfo } from './ListInfo'; import { ShowMore } from './ShowMore'; const App = () => ( <ShowMoreProvider> <ListInfo /> <ShowMore /> </ShowMoreProvider> );
Key Notes
- Safe HTML Parsing: We use
DOMParserto extract text from the HTML string instead ofdangerouslySetInnerHTMLto avoid XSS risks. - Flexibility: You can adjust how many items are shown when truncated by changing the slice index (
slice(0, 2)to any number). - State Control: The
ShowMorecomponent automatically enables truncation when it's present—no extra configuration needed.
内容的提问来源于stack exchange,提问作者Sam

