handle+事件名
命名 function handlePlayClick() {
alert(`Playing`);
}
function PlayButton() {
function handlePlayClick() {
alert(`Playing`);
}
return (
<Button handleClick={handlePlayClick}>
Play "{movieName}"
</Button>
);
}
function UploadButton() {
return (
<Button handleClick={() => alert('Uploading!')}>
Upload Image
</Button>
);
}
handlePlayClick
并非handlePlayClick()
!后者会在组件渲染时执行!)onClick
:事件名,仅支持浏览器事件名称。function Button({ handleClick}) {
function handlePlayClick() {
alert(`Playing`);
}
return (
<div>
<button onClick={handlePlayClick}></button>
<button onClick={handleClick}></button>
// 匿名
<button onClick={() => alert('Uploading!')}></button>
</div>
);
}
onClick
事件,接着事件会冒泡上传;<div id={1} className="Toolbar" onClick={() => {alert('You clicked on the toolbar!');}}>
<button id={2} onDoubleClick={() => alert('Playing!')}>
<button id={3} onClick={() => alert('Uploading!')}>Uploading</button>
</button>
</div>
e.stopPropagation()
Capture
获取被捕获的事件,eg:onClickCapture
<div id={1} className="Toolbar" onClick={e => {
e.stopPropagation();
alert('You clicked on the toolbar!');
}}>
......
</div>
e.preventDefault()
: 阻止了少数事件的默认浏览器行为e.preventDefault()
可以阻止这一行为。 <form onSubmit={e => {
e.preventDefault();
alert('Submitting!');
}}>......
</form>
use
开头的函数⚠️只能在组件或自定义的钩子函数的顶层被调用。 不能在条件、循环或其他嵌套函数中调用。
useState
import { useState } from 'react';
something
是状态变量,setSomething
是设置函数。(均为自定义)const [something, setSomething] = useState(0);
something
为只读,应通过setSomething
函数创建一个新的值去更新!something
是一个对象时person
对象部分属性function handleChange(e) {
setPerson({
firstName: e.target.value, // New first name from the input
lastName: person.lastName,
email: person.email
});
}
function handleChange(e) {
setPerson({
...person, // Copy the old fields
firstName: e.target.value // But override this one
});
}
[
变量名]
写法function handleChange(e) {
setPerson({
...person,
[e.target.name]: e.target.value
});
}
import React from "react";
import { useImmer } from "use-immer";
function App() {
......
function updateName(name) {
updatePerson(draft => {
draft.name = name;
});
}
......
}
something
是一个数组时setArtists([
...artists,
{ id: nextId++, name: name } // Put new item at the end
]);
或
setArtists([
{ id: nextId++, name: name }, // Put new item at the head
...artists
]);
setArtists(
artists.filter(a => a.id !== artist.id)
);
map()
:遍历每个元素filter()
:返还条件为true的元素artists.map(a => <li>a/<li>)
artists.map((a,i) => <li key={i}>a/<li>)
artists.filter(a => a.id !== artist.id)
artists.filter((a,i) => i<10)
slice()
方法拷贝数组后,操作新数组。/ 拷贝
let citrus = [...fruits] / 拷贝
let citrus = fruits.slice(); / 全部拷贝
let citrus = fruits.slice(1, 3); / 拷贝fruits[1,3)
/ 操作
const item = citrus.find(a => a.id === 2);
citrus.reverse();
citrus.sort();
/ 更新
setFruits(citrus);
setMyList(myList.map(artwork => {
return { ...artwork, seen: nextSeen };
}));
something
状态值存储在组件之外(组件存储的只是状态值的快照),每次setSomething()
更改的是组件外的状态值,当组件“稳定”(没有代码在执行)后,React会更改DOM从而触发组件渲染,通过渲染将更新后的状态值刷新到页面!!!number
默认为0alert(number)
的值仍然是0!import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(number + 5);
alert(number);
}}>+5</button>
</>
)
}
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
setEnabled(e => !e);
setLastName(ln => ln.reverse());
setFriendCount(fc => fc * 2);