React中动态设置CSS类的方法求助:如何为AnnotationLabel组件动态绑定className以避免重复创建组件
Hey there! Great question—this is exactly the kind of scenario where using a configuration object to keep your code DRY makes perfect sense. Instead of duplicating the AnnotationLabel component for each country, you can centralize all the country-specific data (like the CSS class, title, and click handler) and dynamically pass those values to a single component instance.
Here's how to do it step by step:
Step 1: Create a Country Configuration Object
First, define an object that holds all the unique properties for each country. This will make it easy to reference and reuse these values later:
const countryConfigs = { usa: { className: "country-bg-usa", title: "USA".toUpperCase(), onClick: () => gotoCountry("USA") }, canada: { className: "country-bg-canada", title: "CANADA".toUpperCase(), onClick: () => gotoCountry("CANADA") }, suriname: { className: "country-bg-suriname", title: "SURINAME".toUpperCase(), onClick: () => gotoCountry("SURINAME") }, ireland: { className: "country-bg-ireland", title: "IRELAND".toUpperCase(), onClick: () => gotoCountry("IRELAND") }, unitedKingdom: { className: "country-bg-unitedKingdom", title: "UNITED KINGDOM".toUpperCase(), onClick: () => gotoCountry("UNITED KINGDOM") }, singapore: { className: "country-bg-singapore", title: "SINGAPORE".toUpperCase(), onClick: () => gotoCountry("SINGAPORE") } };
Step 2: Render Components Dynamically
Now you can use this config to render either a single country label or all of them without repeating component code.
Option 1: Render All Country Labels
If you need to display multiple labels at once, loop through the config object with Object.values() and map each entry to an AnnotationLabel:
// Inside your component's JSX return return ( <div className="annotation-container"> {Object.values(countryConfigs).map((country, index) => ( <AnnotationLabel key={country.title} // Use a unique key for better React performance x={120} // Adjust these values if they vary per country—add them to the config if needed! y={160} ny={140} nx={20} color="#afb1b3" editMode={false} className={country.className} note={{ title: country.title, align: "middle", orientation: "topBottom", bgPadding: { left: 7, right: 5 }, padding: 0, titleColor: "white" }} events={{ onClick: country.onClick }} /> ))} </div> );
Option 2: Render a Single Country Label
If you only need to render one label at a time (e.g., based on user selection), grab the relevant config entry and pass its values to the component:
// Example: Get the selected country from state or props const selectedCountry = "usa"; const country = countryConfigs[selectedCountry]; return ( <AnnotationLabel x={120} y={160} ny={140} nx={20} color="#afb1b3" editMode={false} className={country.className} note={{ title: country.title, align: "middle", orientation: "topBottom", bgPadding: { left: 7, right: 5 }, padding: 0, titleColor: "white" }} events={{ onClick: country.onClick }} /> );
Bonus: Handle Varying Props
If properties like x, y, or bgPadding differ per country, just add them to the config object. For example:
const countryConfigs = { usa: { className: "country-bg-usa", title: "USA".toUpperCase(), onClick: () => gotoCountry("USA"), x: 120, y: 160 }, canada: { className: "country-bg-canada", title: "CANADA".toUpperCase(), onClick: () => gotoCountry("CANADA"), x: 150, y: 180 } };
Then in your JSX, replace the hardcoded values with country.x and country.y.
This approach keeps your code clean, maintainable, and avoids unnecessary component duplication. Just make sure your CSS is properly imported so the classes are available to the component!
内容的提问来源于stack exchange,提问作者Manu Singh

