组件API
组件API这里指的是在组件内可以使用的方法,主要有:
- 设置状态:setState
- 替换状态:replaceState
- 设置属性:setProps
- 替换属性:replaceProps
- 强制更新:forceUpdate
- 获取DOM节点:findDOMNode
- 判断组件挂载状态:isMounted (在es6被废弃)
setState
setState(object nextState[, function callback])
参数说明
nextState:将要设置的新状态,该状态会和当前的state合并
callback:可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。
方法作用:合并nextState和当前state,并重新渲染组件。setState是React事件处理函数中和请求回调函数中触发UI更新的主要方法。
注意:不要在组件内部通过改变this.state来改变状态(不会触发渲染)
setState不会立即处理,会优化批量处理
setState总是会触发重绘,除非定义了条件渲染:shouldComponentUpdate()
注意:this.props 和 this.state 是异步更新的,不能同时依靠这两个状态来确定下一个状态
// 错误用法:
this.setState({
counter: this.state.counter + this.props.increment,
});
// 可以使用:
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
// 或:
this.setState(function(prevState, props) {
return {
counter: prevState.counter + props.increment
};
});
注意:react第一参数传入对象和传入函数是不同的效果
如果传入对象,在一次执行中多次的setState会先放到状态队列中,同步方法执行完毕后才会批处理执行,并且对于相同的state入参会进行合并,同时由于传入的是一个对象,在该对象被传入时state就被解析成数据,所以多次结果中state都是历史值而不是最新值
如果传入函数,则每次函数入参都是最新值
// 多个对象中,this.state值相同
// 假设this.state.x=0
// 第一次:赋值x:0+1
// 第二次:赋值x:0+2
// 第三次:赋值x:0+3
// 最终结果就是x=3
this.setState({
x:this.state.x+1
})
this.setState({
x:this.state.x+2
})
this.setState({
x:this.state.x+3
})
// 传入函数,每次函数入参都是最新值
this.setState((state,props)=>{
console.log(state) // 0
return{x:state.x+1}
})
this.setState((state,props)=>{
console.log(state) // 1
return{x:state.x+2}
})
this.setState((state,props)=>{
console.log(state,props) // 3
return{x:state.x+3}
})
关于setState是同步还是异步:
18.x以上版本,是异步的,会批量更新,无论是否在react的调度流程中!
18.x以下的版本,需要分情况讨论:setTimeout setInterval ,直接在 DOM 上绑定原生事件等。这些都不会走 React 的调度流程,在这种情况下调用 setState ,就是同步的。 否则就是异步的。
需要注意的是: setState 同步执行的情况下, DOM 也会被同步更新,也就意味着如果你多次 setState ,会导致多次更新,这是毫无意义并且浪费性能的。
特别注意:在函数组件中,使用setTimeout去改变state并打印,结果还是原来的state,因为此时获取的state因为闭包的原因,拿的依然是原来的state,如果项观察到可以使用document.querySelector('#id').innerHTML,将state放在该id内容中即可!
useState也是一样的
关于函数组件的回调函数使用state出现闭包问题:
setTimeout(() => {
setCount(count + 2)
}, 0)
如果在函数组件中的一个函数中,有一个回调函数,使用了state,则会在回调函数创建时产生一个闭包,里面存放了创建时的state值!!所以回调函数执行时拿的是原来的值!可以使用:setCount(count => count + 2)来避免
replaceState
replaceState(object nextState[, function callback])
nextState:将要设置的新状态,该状态会替换当前的state。
callback:可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。
注意:replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。
setProps
setProps(object nextProps[, function callback])
nextProps:将要设置的新属性,该状态会和当前的props合并
callback:可选参数,回调函数。该函数会在setProps设置成功,且组件重新渲染后调用。
设置组件参数属性,并重新渲染组件。
props相当于组件的数据流,它总是会从父组件向下传递至所有的子组件中。当和一个外部的JavaScript应用集成时,我们可能会需要向组件传递数据或通知React.render()组件需要重新渲染,可以使用setProps()。更新组件,我可以在节点上再次调用React.render(),也可以通过setProps()方法改变组件属性,触发组件重新渲染。
replaceProps
replaceProps(object nextProps[, function callback])
nextProps:将要设置的新属性,该属性会替换当前的props。
callback:可选参数,回调函数。该函数会在replaceProps设置成功,且组件重新渲染后调用。
replaceProps()方法与setProps类似,但它会删除原有 props。
forceUpdate
forceUpdate([function callback])
callback:可选参数,回调函数。该函数会在组件render()方法调用后调用。
forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。
forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后???),通过该方法通知React需要调用render()
一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。
findDOMNode
DOMElement findDOMNode(组件元素引用)
返回值:DOM元素DOMElement
如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。
getNodeInstance() {
// 使用这种方式拿到的是组件的实例,此时是一个react组件
const nodeInstance = this.refs.navBox;
// 使用这种方式拿到的是dom元素,可以获取offsetWidth等属性
let initialNode = findDomNode(this.refs.navBox);
}
function WapShop() {
return (
<div>
<NavBox ref="navBox" />
</div>
);
}
isMounted
bool isMounted()
返回值:true或false,表示组件是否已挂载到DOM中
isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。
es6废弃后,使用如下方法来替代:
componentDidMount() {
this.mounted = true;
}
componentWillUnmount() {
this.mounted = false;
}
本文深入讲解React组件内部可用的API,包括setState、replaceState、setProps等方法的使用细节及注意事项,帮助开发者掌握组件状态管理和更新的最佳实践。
735

被折叠的 条评论
为什么被折叠?



