我有一个聊天小部件,每当我向上滚动时,它就会弹出一个消息数组。我现在面临的问题是,当消息加载时,滑块固定在顶部。我想让它关注上一个数组的最后一个索引元素。我发现我可以通过传递索引来进行动态引用,但我也需要知道使用哪种滚动函数来实现这一点
handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
//scroll to testNode
}
}
render() {
return (
<div>
<div ref="test"></div>
</div>)
}
React 16.8 +,功能组件
const ScrollDemo = () => {
const myRef = useRef(null)
const executeScroll = () => myRef.current.scrollIntoView()
// run this function from an event handler or an effect to execute scroll
return (
<>
<div ref={myRef}>Element to scroll to</div>
<button onClick={executeScroll}> Click to scroll </button>
</>
)
}
点击这里查看StackBlits的完整演示
React 16.3 +,类组件
class ReadyToScroll extends Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
}
render() {
return <div ref={this.myRef}>Element to scroll to</div>
}
executeScroll = () => this.myRef.current.scrollIntoView()
// run this method to execute scrolling.
}
类组件-引用回调
class ReadyToScroll extends Component {
render() {
return <div ref={ (ref) => this.myRef=ref }>Element to scroll to</div>
}
executeScroll = () => this.myRef.scrollIntoView()
// run this method to execute scrolling.
}
不要使用字符串引用。
字符串裁判损害性能,不可组合,并且正在被淘汰(2018年8月)。
字符串引用有一些问题,被认为是遗留的,而且很可能是
在将来的版本中被删除。[官方React文档]
resource1resource2
可选:平滑滚动动画
/* css */
html {
scroll-behavior: smooth;
}
传递ref给一个子对象
我们希望ref附加到一个dom元素,而不是一个react组件。所以当把它传递给子组件时,我们不能给prop ref命名。
const MyComponent = () => {
const myRef = useRef(null)
return <ChildComp refProp={myRef}></ChildComp>
}
然后将ref prop附加到dom元素上。
const ChildComp = (props) => {
return <div ref={props.refProp} />
}
也许有人会遇到像我这样的情况
https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node
如何度量DOM节点?
测量DOM节点位置或大小的一种基本方法是使用回调ref。每当ref附加到不同的节点时,React就会调用该回调。下面是一个小演示:
function MeasureExample() {
const [height, setHeight] = useState(0);
const measuredRef = useCallback(node => {
if (node !== null) {
setHeight(node.getBoundingClientRect().height);// you can scroll in this line
}
}, []);
return (
<>
<h1 ref={measuredRef}>Hello, world</h1>
<h2>The above header is {Math.round(height)}px tall</h2>
</>
);
}
在本例中,我们没有选择useRef,因为对象引用不会通知我们当前引用值的更改。使用回调引用可以确保即使稍后子组件显示了被测量的节点(例如,在响应单击时),我们仍然会在父组件中得到关于它的通知,并可以更新测量值。
注意,我们将[]作为依赖数组传递给useCallback。这确保了我们的ref回调在重新渲染之间不会改变,所以React不会不必要地调用它。
在这个例子中,回调ref只会在组件挂载和卸载时被调用,因为呈现的组件在任何重新呈现器中都保持存在。如果你想在组件调整大小时收到通知,你可以使用ResizeObserver或在其上构建的第三方Hook。
2019年7月-专用钩子/函数
专用的钩子/函数可以隐藏实现细节,并为组件提供简单的API。
React 16.8 +功能组件
const useScroll = () => {
const elRef = useRef(null);
const executeScroll = () => elRef.current.scrollIntoView();
return [executeScroll, elRef];
};
在任何功能组件中使用它。
const ScrollDemo = () => {
const [executeScroll, elRef] = useScroll()
useEffect(executeScroll, []) // Runs after component mounts
return <div ref={elRef}>Element to scroll to</div>
}
完整的演示
React 16.3 +类组件
const utilizeScroll = () => {
const elRef = React.createRef();
const executeScroll = () => elRef.current.scrollIntoView();
return { executeScroll, elRef };
};
在任何类组件中使用它。
class ScrollDemo extends Component {
constructor(props) {
super(props);
this.elScroll = utilizeScroll();
}
componentDidMount() {
this.elScroll.executeScroll();
}
render(){
return <div ref={this.elScroll.elRef}>Element to scroll to</div>
}
}
完整的演示