React如何正确编写可传参的菜谱生成函数组件?
问题根因
代码没有任何渲染输出是两个核心错误导致的:
- 违反React函数组件的参数约定:所有通过
React.createElement第二个参数传入的属性,会被封装为props对象,作为函数的第一个参数传入组件。你写的recipeWriter没有定义入参,根本拿不到传入的recipeArray和name值。 - 组件内部引用的是外层作用域里初始值为空数组的
recipeArray、未赋值的name全局变量,没有任何有效渲染数据。
另外你写的CSS里定义了.steps类的样式,但原代码没有给步骤列表加对应类名,就算渲染出内容样式也不会生效。
你给出的可运行示例是直接在组件内引用全局硬编码变量,这种写法的组件完全无法复用,不符合React组件设计的思路,通过props传参的写法才是正确的可复用实现方式。
修正后的可运行代码
// 原始数据 const steps = ['warm water', 'put egg to boil', 'boil finishes', 'scrape off shell'], dishName = 'making eggs' // 函数组件显式接收props参数,推荐直接在参数位解构需要的属性 // 注意组件名首字母大写,是React区分自定义组件和原生标签的约定 function RecipeWriter({ recipeArray, name }) { return React.createElement( 'section', { className: 'recipe' }, React.createElement('h3', { className: 'recipeName' }, name), // 列表套ul标签符合HTML语义,加上steps类名匹配CSS样式 React.createElement('ul', { className: 'steps' }, recipeArray.map((item, idx) => React.createElement('li', { key: idx }, item) ) ) ) } // React16及更早版本渲染逻辑 ReactDOM.render( React.createElement(RecipeWriter, { recipeArray: steps, name: dishName }), document.getElementById('root') )
如果你用的是React18版本,旧的
ReactDOM.renderAPI已经被废弃,需要改用新的根节点渲染写法:const root = ReactDOM.createRoot(document.getElementById('root')) root.render( React.createElement(RecipeWriter, { recipeArray: steps, name: dishName }) )
函数组件编写最佳实践
- 组件名必须首字母大写,所有自定义组件都遵循这个规则,React会把小写开头的标签识别为原生HTML标签
- 组件渲染依赖的所有数据都通过props传入,不要依赖组件外层的可变全局变量,保证组件是纯函数:相同输入永远返回相同的渲染结果
- 渲染列表项时必须加唯一的
key属性,如果列表存在增删、排序操作,不要用遍历索引作为key,优先使用数据本身自带的唯一ID,避免渲染错乱 - 原生HTML的
class属性要写成className、for属性要写成htmlFor,和DOM API的属性命名保持一致 - 尽量减少组件内部的副作用逻辑,所有和渲染无关的副作用要放到对应的Hook里处理(React16.8+版本适用)
内容的提问来源于stack exchange,提问作者Prabhdeep Singh
相关产品推荐
相关产品推荐

