1. 受控组件、非受控组件的使用
1.1 自己提交form的表单
import React, { PureComponent } from "react"
export class App extends PureComponent {
constructor() {
super()
this.state = {
username: "kobe"
}
}
inputChange(event) {
console.log("inputChange: ", event.target.value)
this.setState({ username: event.target.value }, console.log(this.state.username))
}
handleSubmitClick(event) {
event.preventDefault()
console.log("获取所有的输入内容")
console.log(this.state.username)
}
handleChange(event) {
this.setState({ username: event.target.value })
}
render() {
const { username } = this.state
return (
<div>
// 不推荐直接在 form 表单上绑定 action,最好的方式是内部使用 button,然后在 form 上监听事件
<form onSubmit={e => this.handleSubmitClick(e)}>
{/* 1. 用户名和密码 */}
<label htmlFor="username">
用户: <input id="username" type="text" value={username} name="username" onChange={e => this.handleChange(e)} />
</label>
<button type="submit">注册</button>
</form>
</div>
)
}
}
export default App
1.2 多个表单使用同一个函数
import React, { PureComponent } from "react"
export class App extends PureComponent {
constructor() {
super()
this.state = {
username: "kobe",
password: 123456
}
}
handleSubmitClick(event) {
event.preventDefault()
console.log("获取所有的输入内容")
console.log(this.state.username, this.state.password)
}
handleInputChange(event) {
const keyword = event.target.name
this.setState({
[keyword]: event.target.value
})
}
render() {
const { username, password } = this.state
return (
<div>
<form onSubmit={e => this.handleSubmitClick(e)}>
{/* 1. 用户名和密码 */}
<label htmlFor="username">
用户:
<input id="username" type="text" value={username} name="username" onChange={e => this.handleInputChange(e)} />
</label>
<label htmlFor="password">
密码:
<input id="password" type="password" value={password} name="password" onChange={e => this.handleInputChange(e)} />
</label>
<button type="submit">注册</button>
</form>
</div>
)
}
}
export default App
1.3 CheckBox 的单选和多选
import React, { PureComponent } from "react"
export class App extends PureComponent {
constructor() {
super()
this.state = {
username: "kobe",
password: 123456,
isAgree: false,
hobbies: [
{ value: "sing", text: "唱", isChecked: false },
{ value: "dance", text: "跳", isChecked: false },
{ value: "rap", text: "rap", isChecked: false }
]
}
}
inputChange(event) {
console.log("inputChange: ", event.target.value)
this.setState({ username: event.target.value }, console.log(this.state.username))
}
handleSubmitClick(event) {
event.preventDefault()
console.log("获取所有的输入内容")
console.log(this.state.username, this.state.password)
console.log(this.state.hobbies.filter(hobby => hobby.isChecked).map(hobby => hobby.value))
}
handleInputChange(event) {
const target = event.target
const value = target.type === "checkbox" ? target.checked : target.value
const name = target.name
target.type === "checkbox"
? this.setState({ isAgree: value })
: this.setState({
[name]: value
})
}
handlehobbiesChange(e, index) {
const hobbies = [...this.state.hobbies]
hobbies[index].isChecked = e.target.checked
this.setState({ hobbies })
}
render() {
const { username, password, isAgree, hobbies } = this.state
return (
<div>
<form onSubmit={e => this.handleSubmitClick(e)}>
{/* 1. 用户名和密码 */}
<div>
<label htmlFor="username">
用户:
<input id="username" type="text" value={username} name="username" onChange={e => this.handleInputChange(e)} />
</label>
<label htmlFor="password">
密码:
<input id="password" type="password" value={password} name="password" onChange={e => this.handleInputChange(e)} />
</label>
</div>
{/* 2. checkbox */}
<div>
<label htmlFor="agree">
<input type="checkbox" id="agree" checked={isAgree} onChange={e => this.handleInputChange(e)} />
同意协议
</label>
</div>
{/* 3. checkbox 多选 */}
<div>
{hobbies.map((hobby, index) => (
<label htmlFor={hobby.value} key={hobby.value}>
<input id={hobby.value} type="checkbox" checked={hobby.isChecked} onChange={e => this.handlehobbiesChange(e, index)} />
{hobby.text}
</label>
))}
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
</div>
)
}
}
export default App
1.4 select 的单选和多选
import React, { PureComponent } from "react"
export class App extends PureComponent {
constructor() {
super()
this.state = {
fruit: []
}
}
handleSubmitClick(event) {
event.preventDefault()
console.log("获取所有的输入内容")
console.log(this.state.fruit)
}
handleFruitChange(event) {
const options = Array.from(event.target.selectedOptions)
const vlaues = options.map(fruit => fruit.value)
this.setState({
fruit: vlaues
})
const vlaues2 = Array.from(event.target.selectedOptions, fruit => fruit.value)
console.log(vlaues2)
}
render() {
const { fruit } = this.state
return (
<div>
<select value={fruit} multiple onChange={e => this.handleFruitChange(e)}>
<option value="apple">苹果</option>
<option value="orange">橘子</option>
<option value="banana">香蕉</option>
</select>
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
</div>
)
}
}
export default App
1.5 非受控组件
import React, { createRef, PureComponent } from "react"
export class App extends PureComponent {
constructor() {
super()
this.introRef = createRef()
}
render() {
const { intro } = this.state
return (
<div>
<input type="text" defaultValue={intro} ref={this.introRef} />
</div>
)
}
}
export default App
2. 高阶组件
2.1 高阶组件的定义和作用
import React, { PureComponent } from "react"
function hoc(Cpn) {
class NewCpn extends PureComponent {
render() {
return <Cpn />
}
}
return NewCpn
}
class HelloWorld extends PureComponent {
render() {
return <h1>Hello World</h1>
}
}
const HelloWorldHOC = hoc(HelloWorld)
export class App extends PureComponent {
render() {
return (
<div>
<HelloWorldHOC />
</div>
)
}
}
export default App
2.2 高阶组件应用-props增强
import { PureComponent } from "react"
function enhancedUserInfo(OriginComponent) {
class NewComponent extends PureComponent {
constructor() {
super()
this.state = {
userInfo: {
name: "kobe",
level: 99
}
}
}
render() {
const { userInfo } = this.state
return <OriginComponent {...this.props} {...userInfo} />
}
}
return NewComponent
}
export default enhancedUserInfo
import React, { PureComponent } from "react"
import enhancedUserInfo from "../hoc/enhanced_props"
export class About extends PureComponent {
render() {
const { name, level } = this.props
return (
<div>
About: {name}-{level}
</div>
)
}
}
export default enhancedUserInfo(About)
import React, { PureComponent } from "react"
import enhancedUserInfo from "./hoc/enhanced_props"
import About from "./pages/About"
const Home = enhancedUserInfo(function (props) {
return (
<h1>
Home: {props.name}-{props.level}-{props.banners}
</h1>
)
})
const Profile = enhancedUserInfo(function (props) {
return (
<h1>
Profile: {props.name}-{props.level}
</h1>
)
})
const HelloFriend = enhancedUserInfo(function (props) {
return (
<h1>
HelloFriend: {props.name}-{props.level}
</h1>
)
})
export class App extends PureComponent {
render() {
return (
<div>
<Home banners={["swipe1", "swipe2"]} />
<Profile />
<HelloFriend />
<About />
</div>
)
}
}
export default App
2.3 context 共享
import React, { PureComponent } from "react"
import ThemeContext from "../context/theme-context"
import WithTheme from "../hoc/with_theme"
export class Product extends PureComponent {
render() {
const { color, size } = this.props
return (
<div>
Product:{color}-{size}
</div>
)
}
}
export default WithTheme(Product)
import React, { PureComponent } from "react"
import ThemeContext from "./context/theme-context"
import Product from "./pages/Product"
export class App extends PureComponent {
render() {
return (
<div>
<ThemeContext.Provider value={{ color: "red", size: 30 }}>
<Product />
</ThemeContext.Provider>
</div>
)
}
}
export default App
2.4 登录鉴权
function LoginAuth(OriginComponent) {
return props => {
const token = window.localStorage.getItem("token")
return token ? <OriginComponent {...props} /> : <h2>请先登录, 再跳转到其他页面</h2>
}
}
export default LoginAuth
import React, { PureComponent } from "react"
import LoginAuth from "../hoc/login_auth"
export class Cart extends PureComponent {
render() {
return <h2>Cart</h2>
}
}
export default LoginAuth(Cart)
import React, { PureComponent } from "react"
import Cart from "./pages/Cart"
export class App extends PureComponent {
constructor() {
super()
this.state = {
isLogin: false
}
}
loginClick() {
window.localStorage.setItem("token", "lwz")
}
render() {
const { isLogin } = this.state
return (
<div>
<button onClick={e => this.loginClick(e)}>登录</button>
<Cart />
</div>
)
}
}
export default App
2.5 生命周期
import { PureComponent } from "react"
function logRenderTime(OriginComponent) {
return class extends PureComponent {
UNSAFE_componentWillMount() {
this.beginTime = new Date().getTime()
}
componentDidMount() {
this.endTime = new Date().getTime()
const interval = this.endTime - this.beginTime
console.log(`当前页面${OriginComponent.name}花费了${interval}ms来渲染!`)
}
render() {
return <OriginComponent {...this.props} />
}
}
}
export default logRenderTime
import React, { PureComponent } from "react"
import logRenderTime from "../hoc/log_render_time"
export class Detail extends PureComponent {
render() {
return (
<div>
<h2>Detail Page</h2>
<ul>
<li>页面列表1</li>
<li>页面列表2</li>
<li>页面列表3</li>
<li>页面列表4</li>
<li>页面列表5</li>
<li>页面列表6</li>
<li>页面列表7</li>
<li>页面列表8</li>
<li>页面列表9</li>
<li>页面列表10</li>
</ul>
</div>
)
}
}
export default logRenderTime(Detail)
import React, { PureComponent } from "react"
import Detail from "./pages/Detail"
export class App extends PureComponent {
render() {
return (
<div>
<Detail />
</div>
)
}
}
export default App
3. React 的 Protals
<style>
#modal {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
<body>
<div id="root"></div>
<div id="lwz"></div>
<div id="modal"></div>
</body>
import React, { PureComponent } from "react"
import { createPortal } from "react-dom"
import Modal from "./Modal"
export class App extends PureComponent {
render() {
return (
<div>
<h1>Hello World</h1>
{createPortal(<h2>Hello React</h2>, document.querySelector("#lwz"))}
{/* 2. Modal 组件 */}
<Modal>
<h2>我是标题</h2>
<p>我是内容</p>
</Modal>
</div>
)
}
}
export default App
import { PureComponent } from "react"
import { createPortal } from "react-dom"
export class Modal extends PureComponent {
render() {
return createPortal(this.props.children, document.querySelector("#modal"))
}
}
export default Modal
4. React 的 fragment
import React, { Fragment, PureComponent } from "react"
export class App extends PureComponent {
render() {
return (
<Fragment>
<h2>Hello World</h2>
<h2>Hello React</h2>
</Fragment>
)
}
}
export default App
5. StrictModel
5.1 作用
- StrictMode 是一个用来突出显示应用程序中潜在问题的工具:
- 与 Fragment 一样,StrictMode 不会渲染任何可见的 UI;
- 它为其后代元素触发额外的检查和警告;
- 严格模式检查仅在开发模式下运行;它们不会影响生产构建;
5.2 检查内容
- 识别不安全的生命周期:
- 使用过时的ref API
- 检查意外的副作用
- 这个组件的constructor会被调用两次;
- 这是严格模式下故意进行的操作,让你来查看在这里写的一些逻辑代码被调用多次时,是否会产生一些副作用;
- 在生产环境中,是不会被调用两次的;
- 使用废弃的findDOMNode方法
- 在之前的React API中,可以通过findDOMNode来获取DOM,不过已经不推荐使用了,可以自行学习演练一下
- 检测过时的context API
- 早期的Context是通过static属性声明Context对象属性,通过getChildContext返回Context对象等方式来使用Context的;
- 目前这种方式已经不推荐使用,大家可以自行学习了解一下它的用法;