JSX代码讲解

这段React代码主要实现了一个电影列表的展示和修改功能,下面分三部分详细解释:

  1. 状态初始化部分

jsx

复制

const [movies, setMovies] = useState([
  {id:1, title: 'spider man', ratings:3},
  {id:3, title: 'King Lion', ratings:9},
  {id:5, title: 'Super Man', ratings:2},
  {id:7, title: 'spider man', ratings:1},
]);
  • 使用useState钩子创建状态变量movies和更新函数setMovies
  • 初始值是一个包含4个电影对象的数组
  • 每个对象包含三个属性:id(唯一标识)、title(标题)、ratings(评分)
  1. 事件处理函数(存在问题)

jsx

复制

const handleMovie = () => {
  setMovies(movies.map(item => 
    item.id === 1 ? {...movies, title:'jon wick'} : item
  ));
}
  • 意图:点击按钮时修改id为1的电影标题
  • 问题:展开运算符使用错误,应该展开item而不是movies
  • 正确写法应为:

jsx

复制

{...item, title: 'jon wick'} // 正确写法
  1. JSX渲染部分(存在问题)

jsx

复制

return (
  <section className='custom-bg'>
    {movies.map(item => (
      <li key={Math.random()}>{item.title}</li>
    ))}
    <button onClick={handleMovie}>Change Name</button>
  </section>
  <section> 
)
  • 问题1:多个根元素(两个<section>
  • 问题2:列表项缺少父级<ul><ol>
  • 问题3:使用Math.random()作为key值(错误做法)
  • 问题4:最后的<section>标签未闭合

需要改进的方面:

  1. 修正后的handleMovie函数:

jsx

复制

const handleMovie = () => {
  setMovies(movies.map(item => 
    item.id === 1 ? { ...item, title: 'jon wick' } : item
  ));
}
  1. 正确的JSX结构:

jsx

复制

return (
  <div>
    <section className='custom-bg'>
      <ul>
        {movies.map(item => (
          <li key={item.id}>{item.title}</li>  // 使用唯一id作为key
        ))}
      </ul>
      <button onClick={handleMovie}>Change Name</button>
    </section>
    {/* 第二个section如果有内容需要补充 */}
  </div>
)

最终效果:

  • 初始显示4部电影标题
  • 点击按钮后,id为1的电影标题会从”spider man”变为”jon wick”
  • 其他电影信息保持不变
  • 使用正确的key可以保证React的diff算法正常工作

常见问题说明:

  1. 为什么不能用Math.random()作为key?
    • 每次渲染都会生成新key值,导致React无法识别元素
    • 会引起不必要的重新渲染
    • 可能导致表单状态丢失
  2. 为什么需要包裹父元素?
    • JSX要求根元素必须是单个元素
    • 可以用<div><React.Fragment>包裹
  3. 展开运算符(…)的作用:
    • 创建对象的浅拷贝
    • 保持原有属性不变,只修改指定属性
    • 避免直接修改原状态对象

Check Also

创建一个待办清单的REACT组件

import React fr …

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注