一:变量和方法的定义,写法
const message = "this is message"
function App() {
return(
<div>
<h1>this is title</h1>
{message}
</div>
)
}
1.变量
变量被定义在组件之外:变量可以在整个文件里使用
变量被定义在组件之内:变量只可以在组件内部使用
const message = "this is message"
2.方法
一般方法写在组件内部
getMessage 是一个方法,返回一段文本,并在 return 语句中调用它。
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语句,变量声明属于语句,不是表达式,不能出现在{}中
// ①使用引号传递字符串
{"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:表示遍历出来的每一项
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.两个元素
三元运算符
const isLogin = true
// 单个元素
{isLogin && <span>this is span</span>}
// 两个元素
{isLogin?<span>jack</span>:<span>loading</span>}
3.复杂条件渲染
自定义函数+if判断语句
// 定义文章类型
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}
function App(){
const clickHandler = ()=>{
console.log("button按钮点击了")
}
return(
<button onClick={clickHandler}></button>
)
}
2.事件参数e
function App(){
const clickHandler = (e)=>{
console.log("button按钮点击了",e)
}
return <button onClick={clickHandler}>click me</button>
}
3.传递自定义参数
事件绑定的位置改造成箭头函数的写法,在执行clickHandler实际处理业务函数的时候传递实参
onClick 事件本身并不会自动传递参数。所以,通过箭头函数,能够将自定义的参数 "jack" 传递给事件处理函数。
function App(){
const clickHandler = (name)=>{
console.log("button按钮点击了",name)
}
return <button onClick={() => clickHandler("jack")}>click me</button>
}
4.既要传递自定义参数,而且还要事件对象e
function App(){
const clickHandler = (name,e)=>{
console.log("button按钮点击了",name,e)
}
return <button onClick={(e) => clickHandler("jack",e)}>click me</button>
}
五:组件基础使用
一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图ui,渲染组件只需要把组件当成标签书写即可
// 1.定义组件
function Button(){
// 组件内部逻辑
return <button>click me</button>
}
// 2.使用组件
function App(){
return (
<div>
// 自闭和
<Button />
</div>
)
}
六:useState
1.概念
useState是用来给组件添加状态变量的,状态变量一旦发生变化组件的视图ui也会跟着变化
// 导入
import {useState} from "react"
// 1.useState是一个函数,返回值是一个数组
// 2.数组中的第一个参数是状态变量,第二个参数是set函数用来修改状态变量
// 3.useState的参数将作为count的初始值
const [count, setCount] = useState(0)
// 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 对象中的其他属性,避免覆盖整个对象。
const [form, setForm] = useState({
name:"jack",
})
const handleChangeName = ()=>{
setForm({
...form,
name:"john",
})
}
七:基础样式控制-class类名控制
className="foo"
①index.css文件
.foo{
color:blue;
}
②App.js文件
// 导入样式
import "./index.css"
function App(){
return (
<div className="App">
// 自闭和
<span className="foo">this is class foo</span>
</div>
)
}
八:classnames优化类名控制
classnames用来根据条件动态地合并类名。
// 安装方式
npm install classnames
// 使用了classnames库来动态设置React组件中的className
import classNames from "classnames"
className={classNames("nav-item",{active:type === item.type})}
九:案例-评论列表
1.渲染评论列表--map方法遍历
※:只要数据会影响到视图的变化,都应该用useState去做维护
※:状态变量必须有一个初始值。commentList的初始值useState(list)
// 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" 用于为这个 元素添加 CSS 样式
// 条件: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项,哪个做高亮处理
点击谁就把谁的标识记录下来,然后和遍历时的每一项标识做匹配,谁匹配到就设置负责高亮的类名
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>)}