总结版1

## 一：变量和方法的定义,写法
``` java
const message = "this is message"
function App() {
  return(
   <div>
     <h1>this is title</h1>
     {message}
   </div>
  )
}
```
#### 1.变量
变量被定义在组件之外：变量可以在整个文件里使用
变量被定义在组件之内：变量只可以在组件内部使用
``` java
const message = "this is message"
```
#### 2.方法
一般方法写在组件内部
getMessage 是一个方法，返回一段文本，并在 return 语句中调用它。
``` java
function App() {
  // 方法的声明
  const getMessage = () => {
    return "this is a function message";
  };

  return (
    <div>
      <h1>this is title</h1>
      {getMessage()}   // 方法的调用
    </div>
  );
}
```
#### 3.return语句
return语句中写的是HTML，渲染到页面上的内容
#### 4.顺序
一般来说，React 组件内部的代码组织顺序是：变量 方法 return语句（HTML 代码）
#### 5.{}作用
通过{}识别表达式，比如变量，函数调用，方法调用等
注意：if switch语句，变量声明属于语句，不是表达式，不能出现在{}中
``` java
// ①使用引号传递字符串
{"abc"}
// ②使用js变量
const count = 100
{count}
// ③函数调用和方法调用
function getName(){
  return "jack"
}
{getName()}

{new Date().getDate()}
// ④使用js对象
<div style={{color:"red"}}>this is div</div>
```
## 二：遍历列表 map
※：加上key(id)  item：表示遍历出来的每一项
``` java
function App() {
  const list = [
    { id: 1001, name: "Vue" },
    { id: 1002, name: "React" },
    { id: 1003, name: "Angular" }
  ];

  return (
    <ul>
      {list.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}
export default App;
```
## 三：条件渲染
#### 1.单个元素
通过&&控制单个元素的显示与隐藏
#### 2.两个元素
三元运算符
``` java
const isLogin = true
// 单个元素
{isLogin && <span>this is span</span>}
// 两个元素
{isLogin?<span>jack</span>:<span>loading</span>}
```
#### 3.复杂条件渲染
自定义函数＋if判断语句
``` java
// 定义文章类型
const articleType = 3  // 有三种情况 0  1  3

// 定义核心函数：根据文章类型返回不同的jsx模板
function getArticleTem(){
  if(articleType === 0){
    return <div>无图文章</div>
  }else if(articleType === 1){
    return <div>单图文章</div>
  }else{
    return <div>三图文章</div>
  }
}

function App(){
  return (
    <div className="App">
    // 调用函数渲染不同的模板
    {getArticleTem()}
    </div>
  )
}
```
## 四：事件绑定
#### 1.基础绑定
on＋事件名称={事件处理程序}  遵循驼峰命名
绑定点击事件：onClick={clickHandler}
``` java
function App(){
  const clickHandler = ()=>{
     console.log("button按钮点击了")
  }
  return(
    <button onClick={clickHandler}></button>
  )
}
```
#### 2.事件参数e
``` java
function App(){
  const clickHandler = (e)=>{
     console.log("button按钮点击了",e)
  }
  return <button onClick={clickHandler}>click me</button>  
}
```
#### 3.传递自定义参数
事件绑定的位置改造成箭头函数的写法，在执行clickHandler实际处理业务函数的时候传递实参
onClick 事件本身并不会自动传递参数。所以，通过箭头函数，能够将自定义的参数 "jack" 传递给事件处理函数。
``` java
function App(){
  const clickHandler = (name)=>{
     console.log("button按钮点击了",name)
  }
  return <button onClick={() => clickHandler("jack")}>click me</button>  
}
```
#### 4.既要传递自定义参数，而且还要事件对象e
``` java
function App(){
  const clickHandler = (name,e)=>{
     console.log("button按钮点击了",name,e)
  }
  return <button onClick={(e) => clickHandler("jack",e)}>click me</button>  
}
```
## 五：组件基础使用
一个组件就是首字母大写的函数，内部存放了组件的逻辑和视图ui,渲染组件只需要把组件当成标签书写即可
``` java
// 1.定义组件
function Button(){
   // 组件内部逻辑
   return <button>click me</button>
}

// 2.使用组件
function App(){
  return (
     <div>
     // 自闭和
     <Button />
     </div>
  )
}
```
## 六：useState
#### 1.概念
useState是用来给组件添加状态变量的，状态变量一旦发生变化组件的视图ui也会跟着变化
``` java
// 导入
import {useState} from "react"
// 1.useState是一个函数，返回值是一个数组
// 2.数组中的第一个参数是状态变量，第二个参数是set函数用来修改状态变量
// 3.useState的参数将作为count的初始值
const [count, setCount] = useState(0)
```
``` java
// useState实现一个计数器按钮
import {useState} from "react"
function App(){
// 1.调用useState添加一个状态变量
// count:状态变量  setCount：修改状态变量的方法
const [count, setCount] = useState(0)

// 2.点击事件回调
const handleClick =()=>{
  // 作用：用传入的新值修改count,重新使用新的count去渲染ui
  setCount（count+1）
}
  return (
     <div className="App">
     // 使用组件
     <button onClick={handleClick}>{count}</button>
     </div>
  )
}
```
#### 2.useState修改状态的规则
状态是只读的，只能替换不能修改
使用新值替换老值，使用新对象替换老对象
修改对象状态：传给set方法一个全新的对象来进行修改
使用展开运算符 ...form 来保留 form 对象中的其他属性，避免覆盖整个对象。
``` java
const [form, setForm] = useState({
  name:"jack",
})

const handleChangeName = ()=>{
  setForm({
    ...form,
    name:"john",
  })
}
```
## 七：基础样式控制-class类名控制
className="foo"
#### ①index.css文件
``` java
.foo{
   color:blue;
}
```
#### ②App.js文件
``` java
// 导入样式
import "./index.css"

function App(){
  return (
     <div className="App">
     // 自闭和
     <span className="foo">this is class foo</span>
     </div>
  )
}
```
## 八：classnames优化类名控制
classnames用来根据条件动态地合并类名。
```java
// 安装方式
npm install classnames
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899383/e406da4a-faab-4354-9ae7-a02df29b2f60.png)
```java
// 使用了classnames库来动态设置React组件中的className
import classNames from "classnames"
 className={classNames("nav-item",{active:type === item.type})}
```
## 九：案例-评论列表
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899383/11774d7e-ee16-4cc2-95d2-7653accd82dc.png)
#### 1.渲染评论列表--map方法遍历
※：只要数据会影响到视图的变化，都应该用useState去做维护
※：状态变量必须有一个初始值。commentList的初始值useState(list)
```java
// 1.使用useState维护评论列表list
const[commentList,setCommentList]=useState(list)
// 2.遍历渲染评论项
{commentList.map(item=> (
   <div key={item.rpid}>评论项</div>
))}
// 3.修饰细节 头像 用户名 评论内容 评论时间 评论数量
{item.user.avatar}
{item.user.uname}
{item.content}
{item.ctime}
{item.like}
```
#### 2.删除自己的评论
只有自己的评论才显示删除按钮，点击删除按钮，删除评论，列表中不再显示
思路：①条件渲染判断是否是自己的评论
②通过id去做匹配，过滤（用户id和评论列表中id）
⭐filter函数返回一个新数组，不更改老数组。类似于一个漏斗，满足条件的留下，不满足条件的漏下去。比如：一共有五条评论，id分别为12345，用户id和评论区id都为3，那么就把3漏下去，把1245作为一个新的数组返回。保留所有rpid !== id 的评论（即删除 rpid === id 的评论）
⭐所有id都是评论ID（rpid），并不是用户 ID（uid）。
⭐className="delete-btn" 用于为这个 <span> 元素添加 CSS 样式
```java
// 条件：user.id=== item.user.id
// 删除功能
const handleDel = (id)=>{
  console.log(id)
  // 对commentList做过滤处理
  setCommentList(commentList.filter(item=> item.rpid !== id ))
}
{user.uid=== item.user.uid && 
  <span className="delete-btn" onClick={()=> handleDel(item.rpid)}>
  删除
  </span>}
```
#### 3.实现渲染导航Tab和高亮
点击哪个tab项，哪个做高亮处理
点击谁就把谁的标识记录下来，然后和遍历时的每一项标识做匹配，谁匹配到就设置负责高亮的类名
```java
const [type,setType] = useState("hot")
const handleTabChange =(type) =>{
  console.log(type)
  setType(type)
}
const tabs = [
    {type:"hot",text:"最热"},
    {type:"time",text:"最新"},
]
// 高亮类名 active
{tabs.map(item=> 
    <span 
       key={item.type} 
       onClick={()=>handleTabChange(item.type)} 
       className={"nav-item ${type === item.type && "active"}"}>
       {item.text}
    </span>)}
```