一.react refs
ref是react上的特殊属性
在常规的数据流之外强制修改子元素
被修改的可以是react组件实例,或者一个dom元素可以在dom元素上和类组件上添加ref,react组件在加载时将dom元素传入ref的回调,在componentDidMount 或者componentDidUpdate 这些生命周期前执行。
1. dom元素上添加ref
...
handleClick(){
this.nameInput.focus();
}
render(){
return(
<div>
<input ref={(input)=>{this.nameInput = input;}}
<button onClick={this.handleClick}>点击获取输入框焦点</button>
</div>
);
}
2. react组件上添加ref
App.js
otherFunction(){
this.pager.changePage(5);
}
....
render(){
return(
<Pager ref={(pager)=>{this.pager = pager; }} />
);
}
Pager.js
...
changePage(page){
this.setState({
page : page
});
}
...
//在父组件中使用ref给某一子组件传值,并且子组件调用setState修改自身的状态,
//该子组件会重新渲染一次,父组件中的其他组件不会重新render
3. ref和函数式组件
function MyTest(){
let textInput = null;
function handleClick(){
textInput.focus();
}
return(){
<div>
<input ref={(input)=>{textInput=input}/>
<button onClick={handleClick}>点击获取输入框焦点</button>
</div>
}
}
4. 子组件对父组件暴露dom节点
在极少数情况下,可能需要从父组件访问子节点的dom节点,【通常不建议这么做,但是偶尔可以触发焦点或测量dom节点的大小和位置】
App.js
...
render(){
return(
<Sub inputRef={ el => this.inputRef = el; } />
);
}
Sub.js
...
render(){
return(){
<div>
<input ref={this.props.inputRef} />
</div>
}
}
二、react forceUpdate
默认情况下,当组件的 state 或 props 改变时,组件将重新渲染。 如果你的 render() 方法依赖于一些其他数据,你可以告诉 React 组件需要通过调用 forceUpdate() 重新渲染。
调用 forceUpdate() 会导致组件跳过 shouldComponentUpdate() ,直接调用 render()。 这将触发子组件的正常生命周期方法,包括每个子组件的 shouldComponentUpdate() 方法。
forceUpdate就是重新render。有些变量不在state上,但是你又想达到这个变量更新的时候,刷新render;或者state里的某个变量层次太深,更新的时候没有自动触发render。这些时候都可以手动调用forceUpdate自动触发render
Sub.js
class Sub extends React.Component{
construcotor(){
super();
this.name = "yema";
}
refChangeName(name){
this.name = name;
this.forceUpdate();
}
render(){
return (<div>{this.name}</div>);
}
}
App.js
class App extends React.Component{
handleClick(){
this.subRef.refChangeName("yemafuren");
}
render(){
return (<div>
<Sub ref={(sub)=>{this.subRef = sub;}} />
<button onClick={this.handleClick}>click</button>
</div>);
}
}