You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React搜索建议组件渲染时建议列表出现多余分号项问题

React SearchBar联想列表额外渲染分号问题

问题描述

开发带联想建议功能的SearchBar组件时遇到渲染异常:遍历包含5条商品数据的productsData生成建议列表时,列表底部出现了一个来源不明的分号作为额外列表项,效果如下:
搜索栏渲染异常效果

原有问题代码如下:

import React from 'react';
import { FiSearch } from 'react-icons/fi';
import '../CSS/SearchBar.css'
import productsData from './../productsData.json'
import 'bootstrap/dist/css/bootstrap.min.css'
    
class SearchBar extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          typed:""
        }
    
        this.userTyped = this.userTyped.bind(this);
      }  
    
      userTyped(e) {
        this.setState({
          typed: e.target.value
        })
      }
      
      render() {
    
        return (
          <div className='searchbar'>
            <div className='wrapper'> 
              <input 
              type='text'
              value={this.state.typed}
              onChange={this.userTyped}
              />
    
              <button>
                <FiSearch size={18}/>
              </button>
            </div>
    
            <ul className='list-group suggestions'>
              {productsData.map((item) => {
                return (
                  <button id='list-item' className='list-group-item list-group-item-action'>
                    {item.title}
                    </button>
    
                )
              })};
              {/* 注意上面map闭合花括号后面多了个分号 */}
            </ul> 
          </div>
        )
      }
}

问题根因

多余的分号是直接写在代码里的:productsData.map(...) 闭合大括号的外面多写了一个;。
JSX的渲染规则是:只有写在{}插值语法内部的内容会被当做JavaScript表达式解析执行,{}外面的所有普通字符都会被直接当做文本节点渲染到DOM里。这个分号在插值表达式外面,就被直接渲染到了<ul>内部,成了最后一个多余的列表项。

另外代码还有两个不规范的点,会触发警告或潜在问题:

  • 用map遍历渲染列表时,没有给每个遍历生成的顶层元素设置唯一key属性,React会抛出渲染警告
  • <ul>标签的合法直接子元素只能是<li>,直接把<button>作为ul的子元素不符合HTML语义规范;同时多个元素共用同一个idlist-item,违反了id全局唯一的规范。

修复方案

  1. 删掉map表达式闭合大括号后面多余的分号
  2. 给遍历项添加唯一key属性
  3. 用<li>包裹按钮,符合ul的语义要求,移除重复id

修复后的完整代码:

import React from 'react';
import { FiSearch } from 'react-icons/fi';
import '../CSS/SearchBar.css'
import productsData from './../productsData.json'
import 'bootstrap/dist/css/bootstrap.min.css'
    
class SearchBar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      typed:""
    }
    this.userTyped = this.userTyped.bind(this);
  }  

  userTyped(e) {
    this.setState({
      typed: e.target.value
    })
  }
  
  render() {
    return (
      <div className='searchbar'>
        <div className='wrapper'> 
          <input 
            type='text'
            value={this.state.typed}
            onChange={this.userTyped}
          />
          <button>
            <FiSearch size={18}/>
          </button>
        </div>

        <ul className='list-group suggestions'>
          {productsData.map((item, index) => {
            return (
              <li key={item.id || index} className="list-group-item p-0">
                <button 
                  className='list-group-item-action w-100 text-start border-0 bg-transparent p-2'
                >
                  {item.title}
                </button>
              </li>
            )
          })}
        </ul> 
      </div>
    )
  }
}

内容的提问来源于stack exchange,提问作者Alvino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 22:36:20