如何优化本地大体积JSON文件向React模板传参的整洁性?
优化SPA中Legal页面的Props传递与组件渲染
问题背景
开发SPA时,通过URL路径从本地JSON获取Legal类页面的文本内容,当前实现中Legal组件需要向ContentLegal传递大量零散props,且后续新增section时会持续增加props数量,代码冗余且维护成本高。
最优优化方案:重构JSON结构+循环渲染sections
核心思路是将JSON中的零散section字段重构为数组对象,让ContentLegal通过循环渲染所有section,彻底消除大量props传递的问题。
1. 重构data.json结构
把原有的section1XXX、section2XXX字段整合成sections数组,每个section是包含自身内容的对象:
{ "legals": [ { "id": "pp", "title": "Privacy policy", "update": "last update: 10/05/2024", "sections": [ { "title": "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "text1": "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "list": [ "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "Lorem ipsum dolor sit amet, consectetur adipiscing elit" ], "text2": "" // 无内容可留空或省略 }, { "title": "Information you choose to give us", "text1": "When you use hiko, here are the types of information you chose to give us:", "list": [ "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "Lorem ipsum dolor sit amet, consectetur adipiscing elit", "Lorem ipsum dolor sit amet, consectetur adipiscing elit" ], "text2": "" } ] } ] }
2. 简化Legal组件的props传递
现在只需要给ContentLegal传递sections数组即可,无需再写一堆零散props:
import HeaderLegal from "../layouts/HeaderLegal"; import ContentLegal from "../layouts/ContentLegal"; const Legal = () => { const { id } = useParams(); const dataLegal = data.legals.find((legal) => legal.id === id); return ( <div> <NavLegals /> <HeaderLegal title={dataLegal.title} text={dataLegal.update} /> {/* 直接传递sections数组 */} <ContentLegal sections={dataLegal.sections} /> </div> ); };
3. 改造ContentLegal组件实现循环渲染
通过map循环渲染所有section,新增section时无需修改组件代码:
const ContentLegal = ({ sections }) => { return ( <div> {sections.map((section, index) => ( <section key={index}> <h2>{section.title}</h2> {section.text1 && <p>{section.text1}</p>} {section.list && section.list.length > 0 && ( <ul> {section.list.map((item, idx) => ( <li key={idx}>{item}</li> ))} </ul> )} {section.text2 && <p>{section.text2}</p>} </section> ))} </div> ); };
注意:若section的
text1/text2可能为空,可添加条件渲染避免空标签;若section有唯一标识,用该标识作为key比index更优。
其他替代方案
方案1:传递整个dataLegal对象(简化props传递)
如果暂时不想重构JSON,可直接把dataLegal传递给ContentLegal,在组件内部解构需要的字段:
// Legal组件 <ContentLegal data={dataLegal} /> // ContentLegal组件 const ContentLegal = ({ data }) => { return ( <div> <section> <h2>{data.section1Ttitle}</h2> <p>{data.section1Text1}</p> {/* 其他内容... */} </section> {/* 其他section... */} </div> ); };
这种方式减少了props传递的数量,但新增section时仍需修改ContentLegal的渲染逻辑,扩展性不如数组循环。
方案2:拆分Section为独立组件
若每个section的结构差异较大,可把单个section拆成独立组件,在ContentLegal中根据类型渲染:
// 独立Section组件 const LegalSection = ({ title, text1, list, text2 }) => ( <section> <h2>{title}</h2> {text1 && <p>{text1}</p>} {list && <ul>{list.map(item => <li key={item}>{item}</li>)}</ul>} {text2 && <p>{text2}</p>} </section> ); // ContentLegal组件 const ContentLegal = ({ sections }) => ( <div> {sections.map(section => <LegalSection key={section.title} {...section} />)} </div> );
这种方式进一步拆分组件,代码更模块化,适合section结构有细微差异的场景。
内容的提问来源于stack exchange,提问作者itachi uchiha
相关产品推荐
相关产品推荐

