Shopify应用开发:如何通过循环生成JavaScript对象数组简化Polaris组件代码
Dynamic Option Generation for Shopify Polaris Select Component
Hey there! I see you're looking to cut down on that repetitive code for your Polaris Select options. Let's fix this by dynamically generating the options array with a loop, while handling those special cases for 9px and 10px. Also, I noticed a couple of small issues in your original component (like using this in a functional component) that I'll clean up along the way.
Here's the Full Working Code:
import { useState, useCallback } from 'react'; import { Select } from '@shopify/polaris'; const SizeComponentPx = (props) => { // Initialize state with the provided initial value (no `this` in functional components!) const [value, setValue] = useState(props.initialValue); // Clean up the change handler - dependency array only includes values that trigger a re-run const handleSelectChange = useCallback((newValue) => { setValue(newValue); // Call the onChange prop passed from the parent component if (props.onChange) { props.onChange(props.name, newValue); } }, [props.name, props.onChange]); // Dynamically generate the options array const generateSizeOptions = () => { const options = []; // Loop from 0 to 50 inclusive for (let i = 0; i <= 50; i++) { let optionValue = `${i}px`; // Handle special cases for 9px and 10px if (i === 9) { optionValue = "1.4px"; } else if (i === 10) { optionValue = "1.5px"; } options.push({ label: `${i} px`, value: optionValue }); } return options; }; // Generate the options (wrap in useMemo below if you want to optimize re-renders) const sizeOptions = generateSizeOptions(); return ( <div className={`faq_panels ${props.class}`}> <Select label={props.label} options={sizeOptions} onChange={handleSelectChange} value={value} name={props.name} /> </div> ); }; export default SizeComponentPx;
Key Improvements & Explanations:
- Dynamic Option Generation: The
generateSizeOptionsfunction loops from 0 to 50, creating each option object automatically. It checks for your special cases (9 and 10) and overrides the value accordingly—no more copying and pasting 50+ lines of option objects! - Functional Component Fixes: Removed all uses of
this(functional components don't have athiscontext). Instead, we useprops.initialValueto set the initial state, and callprops.onChangedirectly in the handler. - Clean useCallback: The dependency array now only includes
props.nameandprops.onChange, ensuring the callback doesn't re-create unnecessarily unless those props change. - Maintainability: If you ever need to adjust the range or add more special cases, you just modify the loop or conditionals instead of editing dozens of lines of repetitive code.
Optional Optimization:
If you want to avoid re-generating the options array on every render, wrap the generateSizeOptions call in useMemo (since the options don't depend on any props/state):
import { useState, useCallback, useMemo } from 'react'; // ... inside the component ... const sizeOptions = useMemo(() => generateSizeOptions(), []);
This will generate the options once on component mount and reuse them for subsequent renders.
内容的提问来源于stack exchange,提问作者Abdul Rasheed Azar
相关产品推荐
相关产品推荐

