【React】初学React
A. react中如何创建元素
呢?
说明一点:
属性都改为驼峰形式(无障碍属性aria-*除外),
class改成className
B. 变量
或表达式
如何表示呢?大括号{ }
包起来
C. 元素
和组件
的区别
元素
是构成 React 应用
的最小砖块
。元素描述了你在屏幕上想看到的内容。
const element = <h1>Hello, world</h1>;
组件
允许你将 UI
拆分为独立可复用的代码片段
,并对每个片段进行独立构思。
组件,从概念上类似于 JavaScript 函数
。它接受
任意的入参
(即 props
),并返回
用于描述页面展示内容的 React 元素
。
D. React元素
与浏览器的 DOM 元素
的区别
React 元素是不可变对象
。一旦被创建,你就无法更改它的子元素或者属性。一个元素就像电影的单帧:它代表了某个特定时刻的 UI。那如何才能刷新页面上的数据呢?
看下面计时器的例子:
但:React 元素是创建开销极小的普通对象?React 只更新它需要更新的部分
React DOM
会将元素和它的子元素与它们之前的状态进行比较
,并只会进行必要的更新
来使 DOM 达到预期的状态。
你可以使用浏览器的检查元素工具查看上一个例子
来确认这一点。
尽管
每一秒
我们都会新建一个描述整个 UI 树的元素
,React DOM
只会更新实际改变了
的内容
E1. 组件入参props
:只读,不可修改
所有 React
组件都必须像纯函数
一样保护
它们的 props 不被更改
。
纯函数
function sum(a, b) {
return a + b;
}
不纯函数
function withdraw(account, amount) {
account.total -= amount;
}
E2. React中的占位符:类似vue中的slot
E3. 如何像使用vue的$attrs
一样使用React的props
在react
中传递props
,如果一层一层传递
,只需要使用 <Component {...props}></Component>
F. class
组件中添加 state
:请使用setState()
修改
关于state
的几点说明:
① 不要直接修改 state
,代码this.state.comment = 'Hello'
不会重新渲染组件
② 而是应该使用 setState()
: this.setState({comment: 'Hello'})
③ 构造函数是唯一可以给 this.state
赋值的地方
④ state
的更新可能是异步的:
⑤ setState
的更新会被合并
⑥ 组件可以选择把它的
state
作为
props
向下传递到它的子组件中
G. 事件处理
使用 React
时,你一般不需要
使用 addEventListener
为已创建的 DOM 元素
添加监听器。你只需要在该元素初始渲染
的时候添加监听器即可。
当你使用 ES6 class 语法定义一个组件的时候,通常的做法是将事件处理函数声明为 class 中的方法。例如,下面的 Toggle
组件会渲染一个让用户切换开关状态的按钮:
向事件处理程序传递参数
在循环中,通常我们会为事件处理函数传递额外的参数。例如,若 id
是你要删除那一行的 ID
,以下两种方式都可以向事件处理函数传递参数:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
上述两种方式是等价的,分别通过箭头函数和 Function.prototype.bind
来实现。
在这两种情况下,React
的事件对象 e
会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind
的方式,事件对象以及更多的参数将会被隐式的进行传递。
H. 条件渲染if
& 列表 for
JSX 允许在大括号中嵌入任何表达式,所以我们可以内联 map()
返回的结果
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()} value={number} />
)}
</ul>
);
}
I. 表单Form
:受控组件
- 表单元素设置了
value
属性,因此显示的值将始终为this.state.value
,这使得React
的state
成为唯一数据源。 - 由于
handlechange
在每次按键时都会执行并更新state
,因此显示的值将随着用户输入而更新。 - 对于受控组件来说,每个
state
突变都有一个相关的处理函数。这使修改或验证用户输入变得简单。如要求所有输入都大写,可以将handlechange
改为:
handleChange(event) {
this.setState({value: event.target.value.toUpperCase()});
}
处理多个输入:当需要处理多个 input
元素时,我们可以给每个元素添加 name
属性,并让处理函数根据 event.target.name
的值选择要执行的操作。
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label> 参与:
<input name="isGoing" type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label><br />
<label>来宾人数:
<input name="numberOfGuests" type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
受控输入空值:在受控组件上指定 value 的 prop
可以防止用户更改输入。如果指定了 value
,但输入仍可编辑,则可能是意外地将value
设置为 undefined
或 null
。
ReactDOM.render(<input value="hi" />, mountNode);
setTimeout(function() {
ReactDOM.render(<input value={null} />, mountNode);
}, 1000);
成熟的解决方案: 如果你想寻找包含验证、追踪访问字段以及处理表单提交的完整解决方案,使用 Formik 是不错的选择。
文件 input 标签:<input type="file" />
,它的 value 只读
,所以它是 React
中的一个非受控组件。
J. 非受控组件
- 在大多数情况下,我们推荐使用 受控组件 来处理表单数据。在一个受控组件中,表单数据是由 React 组件来管理的。
- 另一种替代方案是使用非受控组件,这时表单数据将交由 DOM 节点来处理。
文件输入:在 React
中,<input type="file" />
始终是一个非受控组件,因为它的值只能由用户设置,而不能通过代码控制
class FileInput extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.fileInput = React.createRef();
}
handleSubmit(event) {
event.preventDefault();
alert(
`Selected file - ${
this.fileInput.current.files[0].name
}`
);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Upload file:
<input type="file" ref={this.fileInput} />
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
}
ReactDOM.render(
<FileInput />,
document.getElementById('root')
);
K. 状态提升【官网案例就不重复了】
- 状态提升是什么意思? 一个最简单的例子:
-
两个子组件需要利用对方的状态
,这时我们就需要用到状态提升 - 具体做法:把两个子组件的状态写到它们的父组件中,然后父组件把状态传递到子组件的props中去,这样子组件也相当于有状态
- 父组件相当于是数据源,这样的话,子组件是没有控制权的
- 那么之前子组件的state怎么办呢?像:
<input value = {this.state.value} onChange = {this.handleChange}/>
- 那就在父组件中写出对应的处理函数,并在函数中更改
state
喜欢的朋友记得点赞、收藏、关注哦!!!