React
React基础之ref的三种书写方式
1.字符串形式的ref(官方将要弃用)
<body>
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component {
showDate = () =>{
let {input1} = this.refs
alert(input1.value)
}
showDate2 = () =>{
let {input2} = this.refs
alert(input2.value)
}
render() {
return(
<div>
<input ref="input1" type="text" placeholder="点击按钮提示信息"/>
<button onClick={this.showDate}>点我</button>
<input ref="input2" type="text" onBlur={this.showDate2} placeholder="失去焦点后提示信息"/>
</div>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
</script>
</body>
2.回调形式的ref
<body>
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component {
showDate = () =>{
let {input1} = this
alert(input1.value)
}
showDate2 = () =>{
let {input2} = this
alert(input2.value)
}
render() {
return(
<div>
<input ref={ c => this.input1 = c } type="text" placeholder="点击按钮提示信息"/>
<button onClick={this.showDate}>点我</button>
<input ref={ c => this.input2 = c } type="text" onBlur={this.showDate2} placeholder="失去焦点后提示信息"/>
</div>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
</script>
</body>
3.createRef创建ref容器(官方最推荐的一种)
<body>
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component {
myRef1 = React.createRef()
myRef2 = React.createRef()
showDate = () =>{
alert(this.myRef1.current.value)
}
showDate2 = () =>{
alert(this.myRef2.current.value)
}
render() {
return(
<div>
<input ref={ this.myRef1 } type="text" placeholder="点击按钮提示信息"/>
<button onClick={this.showDate}>点我</button>
<input ref={ this.myRef2 } type="text" onBlur={this.showDate2} placeholder="失去焦点后提示信息"/>
</div>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
</script>
</body>
注意:因为ref很消耗内存, 所以不要过度使用ref! 不要过度使用ref! 不要过度使用ref!
React基础之dangerouslySetInnerHTML 和 Child
1.Child
-
React.Children 是顶层API之一,为处理 this.props.children 这个封闭的数据结构提供了有用的工具。 -
this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点。
<body>
<div id="test"></div>
<script type="text/babel">
class Child extends React.Component {
render(){
console.log(this)
return <div></div>
}
}
class Demo extends React.Component {
render() {
return(
<div>
<Child>
<h1>今天的天气阴了</h1>
<h1>明天的天气不知道</h1>
</Child>
</div>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
</script>
</body>
效果:
2.dangerouslySetInnerHTML
<body>
<div id="test"></div>
<script type="text/babel">
let message = `
<h1>夏天真好<h1>
<h1>又亮又白</h1><h1>
`
class Demo extends React.Component {
render() {
return(
<div dangerouslySetInnerHTML={{
__html:message
}}>
</div>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
</script>
</body>
效果:
React基础之PureComponent
Component的2个问题
- 只要执行setState(),即使不改变状态数据, 组件也会重新render() ==> 效率低
- 只当前组件重新render(), 就会自动重新render子组件,纵使子组件没有用到父组件的任何数据 ==> 效率低
效率高的做法
只有当组件的state或props数据发生改变时才重新render()
原因
Component中的shouldComponentUpdate()总是返回true
解决
办法1:
重写shouldComponentUpdate()方法
比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
办法2:
使用PureComponent
PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
项目中一般使用PureComponent来优化
注意:
1.只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false
2.不要直接修改state数据, 而是要产生新数据
React基础之非受控组件和受控组件
1.非受控组件
<body>
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component {
dain = (event) =>{
event.preventDefault();
let {username,password} = this
alert(`你的用户名是:${username.value}, 你的密码是: ${password.value}`)
}
render() {
return(
<form onSubmit={this.dain}>
用户名: <input ref={c => this.username = c} type="text" name="username"/>
密码: <input ref={c => this.password = c} type="password" name="password"/>
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
</script>
</body>
2.受控组件, 类似于vue中的 v-model
<body>
<div id="test"></div>
<script type="text/babel">
class Demo extends React.Component {
state = {
username:'',
password:''
}
username = (event) =>{
this.setState({username:event.target.value})
}
password = (event) =>{
this.setState({password:event.target.value})
}
dain = (event) =>{
event.preventDefault();
let {username,password} = this.state
alert(`你的用户名是:${username}, 你的密码是: ${password}`)
}
render() {
return(
<form onSubmit={this.dain}>
用户名: <input onChange={this.username} type="text" name="username"/>
密码: <input onChange={this.password} type="text" name="password" name="password"/>
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
</script>
</body>
React基础之Hooks
1.React Hook/Hooks是什么?
1)Hook是React 16.8.0版本增加的新特性/新语法
2)可以让你在函数组件中使用 state 以及其他的 React 特性
2.三个常用的Hook
1). State Hook: React.useState()
2). Effect Hook: React.useEffect()
3). Ref Hook: React.useRef()
3.State Hook
1). State Hook让函数组件也可以有state状态, 并进行状态数据的读写操作
2). 语法: const [xxx, setXxx] = React.useState(initValue)
3). useState()说明:
参数: 第一次初始化指定的值在内部作缓存
返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数
4). setXxx()2种写法:
setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值
setXxx(value => newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值
案例:
import React,{Component} from 'react';
function Dome(){
const [count,setCount] = React.useState(0)
function add(){
setCount(count => count+1)
}
return(
<div>
<h1>当前求和为: {count}</h1>
<button onClick={add}>点我</button>
</div>
)
}
export default Dome
4.Effect Hook
1). Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
2). React中的副作用操作:
发ajax请求数据获取
设置订阅 / 启动定时器
手动更改真实DOM
3). 语法和说明:
useEffect(() => {
// 在此可以执行任何带副作用操作
return () => { // 在组件卸载前执行
// 在此做一些收尾工作, 比如清除定时器/取消订阅等
}
}, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行
4). 可以把 useEffect Hook 看做如下三个函数的组合
componentDidMount()
componentDidUpdate()
componentWillUnmount()
案例:
import React,{Component} from 'react';
import ReactDOM from 'react-dom';
function Dome(){
const [count,setCount] = React.useState(0)
React.useEffect(()=>{
let timer = setInterval(()=>{
setCount(count => count+1)
},1000)
return ()=>{
clearInterval(timer)
}
},[])
function add(){
setCount(count => count+1)
}
function unmount(){
ReactDOM.unmountComponentAtNode(document.getElementById('root'));
}
return(
<div>
<h1>当前求和为: {count}</h1>
<button onClick={add}>点我</button>
<button onClick={unmount}>点击卸载组件</button>
</div>
)
}
export default Dome
5.Ref Hook
1). Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据
2). 语法: const refContainer = useRef()
3). 作用:保存标签对象,功能与React.createRef()一样
案例:
import React,{Component} from 'react';
function Dome(){
const myRef = React.useRef()
function show(){
alert(myRef.current.value);
}
return(
<div>
<input type="text" ref={myRef}/>
<button onClick={show}>点击提示数据</button>
</div>
)
}
export default Dome
6.自定义Hooks函数
自定义Hooks 函数 和 用Hooks 创建组件很相似,跟我们平时用 JavaScript 写函数几乎一模一样,
可能就是多了些 React Hooks 的特性,自定义 Hooks 函数偏向于功能,而组件偏向于界面和业务逻辑。
案例:自定义Hooks 函数获取窗口大小
import React,{useState,useEffect,useCallback} from 'react'
function useWinSize(){
const [size,setSize] = useState({
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
})
const onResize = useCallback(
() => {
setSize({
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
})
},
[],
)
useEffect(() => {
window.addEventListener('resize:',onResize)
return () => {
window.removeEventListener('resize:',onResize)
}
}, [])
return size;
}
function HWinsize(){
const size=useWinSize()
return(
<div>
页面size:{size.width} x {size.height}
</div>
)
}
export default HWinsize;
注意:
1. React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是唯一的
2.因为ref很消耗内存, 所以不要过度使用ref! 不要过度使用ref! 不要过度使用ref!
3.PureComponent的注意点:
? ? 1) 只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false
? ? 2) 不要直接修改state数据, 而是要产生新数据
总结
本篇文章主要介绍了React的 ref,dangerouslySetInnerHTML和Child,PureComponent,非受控组件和受控组件,Hooks , 其中的注意点作者已经在上面标明了, 最后我想说知识从来不是看看就会的,要多实践,多敲代码.
喜欢文章的可以三连一下
|