前情回顾
上一篇了解到一个React前端项目的基本结构
public/index.html
实际的html页面,react render后的内容渲染到 <div id="root"></div>上
src/index.js
实际React查询入口文件,类似C语言的main方法,核心为react-dom的render方法,React18改为:
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
本篇正文
接下来开始接触React语法中最基本也是最重要的——jsx语法
先来清理一下项目(删除部分icon图标,css样式资源文件和爬虫相关robots.txt),使其结构为:
将index.html和App.js修改为简介版本:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
function App() {
return (
<div>
Hello, React
</div>
);
}
export default App;
删除index.js对index.css的引用
import './index.css';
这样就得到一个相对清爽的项目,使用npm start可看到运行效果
回到最开始的话题,首先什么是jsx? 可以看到App.js 函数中返回了一个html dom节点的东西
function App() {
return (
<div>
Hello, React
</div>
);
}
实际这个字符串最后也被渲染到了最终的程序上。return里就是一个典型的jsx语法:
00. jsx本身是一个表达式, 也就是说可以赋值给一个变量或者做函数返回值
01. jsx语法可以看作js的拓展, 它既不是字符串也不是html
02. jsx具备js的所有功能, 同时还可以被转为html在页面显示(react+react-dom; 有点像Thymeleaf这种模板引擎但又不是)
除了html,还可以做很多事情(jsx中注释语法为 {/* comment content */}),我们修改App函数
const name = "777";
const sum = (a, b) => a + b;
const areUOK = true;
const xiaoming = { name: "小明", age: 18 };
const jsx = <span>I'm jsx</span>;
const aTarget = "_blank";
const aDecoration = "none";
function App() {
// 注意 return的jsx表达式最外层只能有一个父级元素, 一般是<div>, React.Fragment或者<></>
return (
<div>
{/* 这是一个html元素, 使用单标签要正确关闭 */}
<h1>Hello, React</h1>
{/* 这是一个变量, 注意这种动态的东西要用{}包裹住, 下同 */}
<div>{name}</div>
{/* 模板字符串 */}
<div>{`hello, ${name}`}</div>
{/* 表达式 */}
<div>{2 ^ 9 ^ 2}</div>
{/* js内置函数 */}
<div>{Date()}</div>
{/* 自定义函数 */}
<div>{sum(1, 5.1)}</div>
{/* 表达式a控制div显示a */}
{areUOK && <div>I'm very ok</div>}
{/* 表达式b控制二div选一显示 */}
{!areUOK ? <div>I'm very ok</div> : <div>I'm very not ok</div>}{" "}
{/* 不能直接引入对象, 可以先做一个转字符串操作 */}
{/* {xiaoming} */}
{JSON.stringify(xiaoming)}
{/* jsx变量 */}
<div>{jsx}</div>
{/* 动态赋值元素属性, 用{}包裹, style用两层包裹 */}
<a
href="http://localhost:3000"
target={aTarget}
style={{ cursor: "hover", textDecorationLine: { aDecoration } }}
>
链接
</a>
</div>
);
}
效果为:
可以对照着进行修改,体会jsx语法
另外,最常见的就是渲染多个html元素了,这里最常用的是jsx语法+map方法(类似vue的v-for):
// 本例渲染数组, 相当于往ul列表中动态添加li
const fruits = ["Apple", "Banana", "Coconut"];
function App() {
// key属性要求唯一性, 这里简单传入fruit name本身, 实际开发中不推荐
return (
<div>
<h3>水果</h3>
<ul>
{fruits.map((fruit) => (
<li key={fruit}>{fruit}</li>
))}
</ul>
</div>
);
}
实际等同于下面这样,当然实际开发不会这样写,相当于react直接展开了一个jsx元素数组:
const fruitsJSX = [
<li key="apple">apple</li>,
<li key="Banana">Banana</li>,
<li key="Coconut">Coconut</li>,
];
function App() {
return (
<div>
<h3>水果</h3>
<ul>{fruitsJSX}</ul>
</div>
);
}