参考JSX 简介 – React (docschina.org)
此文章仅用于,本人的学习记录。
jsx,是JavaScript的语法拓展。一般在react中配合使用。
简介
为什么使用 JSX?
React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合,比如,在 UI 中需要绑定处理事件、在某些时刻状态发生变化时需要通知到 UI,以及需要在 UI 中展示准备好的数据。
React 并没有采用将标记与逻辑进行分离到不同文件这种人为地分离方式,而是通过将二者共同存放在称之为“组件”的松散耦合单元之中,来实现关注点分离。
React 不强制要求使用 JSX,但是大多数人发现,在 JavaScript 代码中将 JSX 和 UI 放在一起时,会在视觉上有辅助作用。它还可以使 React 显示更多有用的错误和警告消息。
元素渲染
元素是构成 React 应用的最小砖块。
与浏览器的 DOM 元素不同,React 元素是创建开销极小的普通对象。React DOM 会负责更新 DOM 来与 React 元素保持一致。
将一个元素渲染为 DOM
假设你的 HTML 文件某处有一个 <div>
:
<div id="root"></div>
我们将其称为“根” DOM 节点,因为该节点内的所有内容都将由 React DOM 管理。
仅使用 React 构建的应用通常只有单一的根 DOM 节点。如果你在将 React 集成进一个已有应用,那么你可以在应用中包含任意多的独立根 DOM 节点。
想要将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入 ReactDOM.render():
const e = <h1>Hello,World!</h1>;
ReactDOM.render(e,document.getElementById('root'));
更新已渲染的元素
React 元素是不可变对象。一个元素就像电影的单帧:它代表了某个特定时刻的 UI。
所以更新UI的方式就是创建一个新的元素并重新渲染。
例如:
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000);
这个例子会在 setInterval() 回调函数,每秒都调用 ReactDOM.render()。
React 只更新它需要更新的部分
React DOM 会将元素和它的子元素与它们之前的状态进行比较,并只会进行必要的更新来使 DOM 达到预期的状态。
组件 & Props
组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思。
函数组件与 class 组件
定义组件最简单的方式就是编写 JavaScript 函数:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
你同时还可以使用 ES6 的 class 来定义组件:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
上述两个组件在 React 里是等效的。
渲染组件
之前我们所定义的都是React元素都是DOM标签;
React可以用户自定义组件;
const e = <Hello name="LiHua"/>
结合之前的函数组件渲染。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Hello name="LiHua" />;
ReactDOM.render(
element,
document.getElementById('root')
);
注意此时渲染的元素,以返回值为主,原本自定义的元素中的Hello不会被展示,展示的应该是return中的Hello。
组合组件
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
提取组件
将组件拆分为更小的组件。
将下列按组件拆分。
function formatDate(date) {
return date.toLocaleDateString();
}
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img
className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">{props.text}</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
const comment = {
date: new Date(),
text: 'I hope you enjoy learning React!',
author: {
name: 'Hello Kitty',
avatarUrl: 'https://placekitten.com/g/64/64',
},
};
ReactDOM.render(
<Comment
date={comment.date}
text={comment.text}
author={comment.author}
/>,
document.getElementById('root')
);
元素传入ReactDOM.render()中,调用comment组件,在传入props参数,在渲染进根节点中。
这里需要赋值,直接在外部定义赋值更清晰。
该组件用于描述一个社交媒体网站上的评论功能,它接收 author
(对象),text
(字符串)以及 date
(日期)作为 props。
该组件由于嵌套的关系,变得难以维护,且很难复用它的各个部分。因此,让我们从中提取一些组件出来。
例如提取Avatar组件。
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
同时修改Comment组件。
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
事件处理
事件处理函数和传统的不同。
传统:
<button onClick="test()">123</button>
React
<button onClick={test}>123</button>
除此之外,传统的HTML可以通关返回false的方式去阻止默认行为。
但在React中不能直接返回false阻止,它必须显示的使用preventDefault()。
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}