《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
也可以使用大括号,来在属性值中插入一个 JavaScript 表达式:
const element = ;
3.3 JSX 防止注入攻击
你可以安全地在 JSX 当中插入用户输入内容:
const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element =
{title}
;React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。
3.4 JSX 表示对象
Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。
以下两种示例代码完全等效:
const element = (
Hello, world!
);
const element = React.createElement(
‘h1’,
{className: ‘greeting’},
‘Hello, world!’
);
React.createElement() 会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:
// 注意:这是简化过的结构
const element = {
type: ‘h1’,
props: {
className: ‘greeting’,
children: ‘Hello, world!’
}
};
这些对象被称为 “React 元素”
它们描述了你希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 以及保持随时更新。
4.1 根Dom节点
假设你的 HTML 文件某处有一个
我们将其称为“根” DOM 节点,因为该节点内的所有内容都将由 React DOM 管理。
4.2渲染Dom根节点
想要将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入 ReactDOM.render():
。。。
const element =
Hello, world
;ReactDOM.render(
element,
document.getElementById(‘root’)
);
4.3 更新已渲染的元素
React 元素是不可变对象。一旦被创建,你就无法更改它的子元素或者属性。一个元素就像电影的单帧:它代表了某个特定时刻的 UI。
根据我们已有的知识,更新 UI 唯一的方式是创建一个全新的元素,并将其传入 ReactDOM.render()。
例如:
function tick() {
const element = (
Hello, world!
It is {new Date().toLocaleTimeString()}.
);
ReactDOM.render(element, document.getElementById(‘root’));
}
setInterval(tick, 1000);
5.1 定义组件
定义组件最简单的方式就是编写 JavaScript 函数:
注意:这里得函数名Welcome首字母必须大写。
function Welcome(props) {
return
Hello, {props.name}
;}
这时这个Welcome就是也组件。
该函数是一个有效的 React 组件,因为它接收唯一带有数据的 “props”(代表属性)对象与并返回一个 React 元素。这类组件被称为“函数组件”,因为它本质上就是 JavaScript 函数。
5.2 适用Es6语法中类定义组件
你同时还可以使用 ES6 的 class 来定义组件:
class Welcome extends React.Component {
render() {
return
Hello, {this.props.name}
;}
}
5.3 渲染租组件
const element = ;
当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。
上面得Welcomef即为:自定义组件
注意: 组件名称必须以大写字母开头。
5.4 Props 的只读性
组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。来看下这个 sum 函数:
纯函数
function sum(a, b) {
return a + b;
}
这样的函数被称为“纯函数”,因为该函数不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果。
相反,下面这个函数则不是纯函数,因为它更改了自己的入参:
function withdraw(account, amount) {
account.total -= amount;
}
6.1 state介绍
State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件。
6.2 将函数组件转换成 class 组件
通过以下五步将 Clock 的函数组件转成 class 组件:
1创建一个同名的 ES6 class,并且继承于 React.Component。
2.添加一个空的 render() 方法。
将函数体移动到 render() 方法之中。
3.在 render() 方法中使用 this.props 替换 props。
4.删除剩余的空函数声明。
如下:
class Clock extends React.Component {
render() {
return (
Hello, world!
It is {this.props.date.toLocaleTimeString()}.
);
}
}
每次组件更新时 render 方法都会被调用,但只要在相同的 DOM 节点中渲染 ,就仅有一个 Clock 组件的
class 实例被创建使用。这就使得我们可以使用如 state 或生命周期方法等很多其他特性。
6.3向 class 组件中添加局部的 state
1.把 render() 方法中的 this.props.date 替换成 this.state.date :
class Clock extends React.Component {
render() {
return (
Hello, world!
It is {this.state.date.toLocaleTimeString()}.
);
}
}
2.添加一个 class 构造函数,然后在该函数中为 this.state 赋初值:
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
Hello, world!
It is {this.state.date.toLocaleTimeString()}.
);
}
}
通过以下方式将 props 传递到父类的构造函数中:
constructor(props) {
super(props);
this.state = {date: new Date()};
}
Class 组件应该始终使用 props 参数来调用父类的构造函数。
3.移除 元素中的 date 属性:
ReactDOM.render(
,
document.getElementById(‘root’)
);
完整代码
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
Hello, world!
It is {this.state.date.toLocaleTimeString()}.
);
}
}
ReactDOM.render(
,
document.getElementById(‘root’)
);
6.4 将生命周期方法添加到 Class 中
当 Clock 组件第一次被渲染到 DOM 中的时候,就为其设置一个计时器。这在 React 中被称为“挂载(mount)”。
同时,当 DOM 中 Clock 组件被删除的时候,应该清除计时器。这在 React 中被称为“卸载(unmount)”。
我们可以为 class 组件声明一些特殊的方法,当组件挂载或卸载时就会去执行这些方法:
class Clock extends React.Component {
…
componentDidMount() {
//componentDidMount() 方法会在组件已经被渲染到 DOM 中后运行
}
componentWillUnmount() {
//组件卸载时调用
}
…
}
这些方法叫做“生命周期方法”。
6.5 正确地使用 State
不要直接修改 State
例如,此代码不会重新渲染组件:
// Wrong
this.state.comment = ‘Hello’;
而是应该使用 setState():
// Correct
this.setState({comment: ‘Hello’});
注意:构造函数是唯一可以给 this.state 赋值的地方:
6.6 State的异步更新
因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
上面使用了箭头函数,不过使用普通的函数也同样可以
6.7State 的更新会被合并
当你调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。
6.8 数据是向下流动的
不管是父组件或是子组件都无法知道某个组件是有状态的还是无状态的,并且它们也并不关心它是函数组件还是 class 组件。
这就是为什么称 state 为局部的或是封装的的原因。除了拥有并设置了它的组件,其他组件都无法访问。
组件可以选择把它的 state 作为 props 向下传递到它的子组件中:
FormattedDate 组件会在其 props 中接收参数 date,但是组件本身无法知道它是来自于 Clock 的 state,或是 Clock 的 props,还是手动输入的:
function FormattedDate(props) {
return
It is {props.date.toLocaleTimeString()}.
;}
7.1 事件的基本使用
React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
7.2 阻止默认行为
在 React 中另一个不同点是你不能通过返回 false 的方式阻止默认行为。
function Form() {
function handleSubmit(e) {
// e 是一个合成事件。React 根据 W3C 规范来定义这些合成事件,所以你不需要担心跨浏览器的兼容性问题。React 事件与原生事件不完全相同。
e.preventDefault();
console.log(‘You clicked submit.’);
}
return (
Submit
);
}
7.3 添加事件处理函数
当你使用 ES6 class 语法定义一个组件的时候,通常的做法是将事件处理函数声明为 class 中的方法。
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// 为了在回调中使用 this
,这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
{this.state.isToggleOn ? ‘ON’ : ‘OFF’}
);
}
}
ReactDOM.render(
,
document.getElementById(‘root’)
);
如果觉得使用 bind 很麻烦,这里有两种方式可以解决。如果你正在使用实验性的 public class fields 语法,你可以使用
class fields 正确的绑定回调函数:
class LoggingButton extends React.Component {
// 此语法确保 handleClick
内的 this
已被绑定。
// 注意: 这是 实验性 语法。
handleClick = () => {
console.log(‘this is:’, this);
}
render() {
return (
Click me
);
}
}
7.4 向事件处理程序传递参数
在循环中,通常我们会为事件处理函数传递额外的参数。例如,若 id 是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row
<button onClick={this.deleteRow.bind(this, id)}>Delete Row
在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。
最后
整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
其实面试这一块早在第一个说的25大面试专题就全都有的。以上提及的这些全部的面试+学习的各种笔记资料,我这差不多来回搞了三个多月,收集整理真的很不容易,其中还有很多自己的一些知识总结。正是因为很麻烦,所以对以上这些学习复习资料感兴趣
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
render() {
return (
Click me
);
}
}
7.4 向事件处理程序传递参数
在循环中,通常我们会为事件处理函数传递额外的参数。例如,若 id 是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row
<button onClick={this.deleteRow.bind(this, id)}>Delete Row
在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。
最后
整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
[外链图片转存中…(img-nhYH4lJN-1714740288865)]
[外链图片转存中…(img-MTppqZQH-1714740288865)]
其实面试这一块早在第一个说的25大面试专题就全都有的。以上提及的这些全部的面试+学习的各种笔记资料,我这差不多来回搞了三个多月,收集整理真的很不容易,其中还有很多自己的一些知识总结。正是因为很麻烦,所以对以上这些学习复习资料感兴趣
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!