J'ai un widget de discussion qui affiche une série de messages à chaque défilement. Le problème auquel je suis confronté est que le curseur reste en haut du chargement des messages. Je souhaite qu'il se concentre sur le dernier élément d'index du tableau précédent. J'ai compris que je pouvais créer des références dynamiques en passant par l'index, mais que je devais également savoir quel type de fonction de défilement utiliser pour atteindre cet objectif.
handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
//scroll to testNode
}
}
render() {
return (
<div>
<div ref="test"></div>
</div>)
}
const scrollToRef = (ref) => window.scrollTo(0, ref.current.offsetTop) // General scroll to element function
const ScrollDemo = () => {
const myRef = useRef(null)
const executeScroll = () => scrollToRef(myRef)
return (
<> {/* React.Fragment*/}
<div ref={myRef}>I wanna be seen</div>
<button onClick={executeScroll}> Click to scroll </button>
</>
)
}
Cliquez ici pour une démonstration complète sur StackBlits
class ReadyToScroll extends Component {
constructor(props) {
super(props)
this.myRef = React.createRef() // Create a ref object
}
render() {
return <div ref={this.myRef}></div>
} // attach the ref property to a dom element
scrollToMyRef = () => window.scrollTo(0, this.myRef.current.offsetTop)
// run this method to execute scrolling.
}
class ReadyToScroll extends Component {
constructor(props){ // Optional, declare a class field to improve readability
super(props)
this.myRef=null
}
render() {
return <div ref={ (ref) => this.myRef=ref }></div>
} // Attach the dom element to a class field
scrollToMyRef = () => window.scrollTo(0, this.myRef.offsetTop)
// run this method to execute scrolling.
}
Les références de chaîne nuisent aux performances, ne sont pas composables et sont en voie de disparition (août 2018).
les références de chaîne ont quelques problèmes, sont considérées comme héritées et sont susceptibles d'être supprimées dans l'une des prochaines versions. [Documentation officielle React]
/* css */
html {
scroll-behavior: smooth;
}
Nous voulons que la référence soit attachée à un élément dom, pas à un composant de réaction. Ainsi, lorsque vous le transmettez à un composant enfant, nous ne pouvons pas nommer le prop prop.
const MyComponent = () => {
const myRef = useRef(null)
return <ChildComp refProp={myRef}></ChildComp>
}
Ensuite, fixez l’appui sur un élément de dom.
const ChildComp = (props) => {
return <div ref={props.refProp} />
}
Trouvez simplement la position supérieure de l'élément que vous avez déjà déterminé https: //www.w3schools.com/Jsref/prop_element_offsettop.asp puis faites défiler jusqu'à cette position via scrollTo
méthode https: //www.w3schools.com/Jsref/met_win_scrollto.asp
Quelque chose comme ça devrait marcher:
handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
window.scrollTo(0, tesNode.offsetTop);
}
}
render() {
return (
<div>
<div ref="test"></div>
</div>)
}
UPDATE:
depuis Réagissez v16.3 la React.createRef()
est préférée
constructor(props) {
super(props);
this.myRef = React.createRef();
}
handleScrollToElement(event) {
if (<some_logic>){
window.scrollTo(0, this.myRef.current.offsetTop);
}
}
render() {
return (
<div>
<div ref={this.myRef}></div>
</div>)
}
cela a fonctionné pour moi
this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
L'utilisation de findDOMNode sera éventuellement obsolète.
La méthode préférée consiste à utiliser des références de rappel.
Vous pouvez également utiliser la méthode scrollIntoView
pour accéder à un élément donné.
handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
tesNode.scrollIntoView();
}
}
render() {
return (
<div>
<div ref="test"></div>
</div>)
}
Je suis peut-être en retard à la fête, mais j’essayais d’appliquer correctement les références dynamiques à mon projet et toutes les réponses que j’ai trouvées jusqu’à ce que je sache ne sont pas satisfaisantes à mon goût, alors j’ai trouvé une solution qui, à mon avis, est simple et utilise la manière native et recommandée de réagir pour créer la réf.
parfois, vous constatez que la façon dont la documentation est écrite suppose que vous avez un nombre connu de vues et que, dans la plupart des cas, ce nombre est inconnu. Vous avez donc besoin d'un moyen de résoudre le problème. Créez des références dynamiques avec le nombre inconnu de vues dont vous avez besoin. montrer dans la classe
donc la solution la plus simple que je pouvais penser et travaillait sans faille était de faire comme suit
class YourClass extends component {
state={
foo:"bar",
dynamicViews:[],
myData:[] //get some data from the web
}
inputRef = React.createRef()
componentDidMount(){
this.createViews()
}
createViews = ()=>{
const trs=[]
for (let i = 1; i < this.state.myData.lenght; i++) {
let ref =`myrefRow ${i}`
this[ref]= React.createRef()
const row = (
<tr ref={this[ref]}>
<td>
`myRow ${i}`
</td>
</tr>
)
trs.Push(row)
}
this.setState({dynamicViews:trs})
}
clickHandler = ()=>{
//const scrollToView = this.inputRef.current.value
//That to select the value of the inputbox bt for demostrate the //example
value=`myrefRow ${30}`
this[value].current.scrollIntoView({ behavior: "smooth", block: "start" });
}
render(){
return(
<div style={{display:"flex", flexDirection:"column"}}>
<Button onClick={this.clickHandler}> Search</Button>
<input ref={this.inputRef}/>
<table>
<tbody>
{this.state.dynamicViews}
<tbody>
<table>
</div>
)
}
}
export default YourClass
de cette façon, le parchemin ira à la rangée que vous cherchez.
acclamations et espère que cela aide les autres
Vous pouvez essayer de cette façon:
handleScrollToElement = e => {
const elementTop = this.gate.offsetTop;
window.scrollTo(0, elementTop);
};
render(){
return(
<h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
)}
Vous pouvez maintenant utiliser useRef
à partir de l’API de hook réactif
https://reactjs.org/docs/hooks-reference.html#useref
let myRef = useRef()
<div ref={myRef}>My Component</div>
window.scrollTo({ behavior: 'smooth', top: myRef.current.offsetTop })
Vous pouvez utiliser quelque chose comme componentDidUpdate
componentDidUpdate() {
var elem = testNode //your ref to the element say testNode in your case;
elem.scrollTop = elem.scrollHeight;
};
Ce qui a fonctionné pour moi:
class MyComponent extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef(); // Create a ref
}
// Scroll to ref function
scrollToMyRef = () => {
window.scrollTo({
top:this.myRef.offsetTop,
// behavior: "smooth" // optional
});
};
// On component mount, scroll to ref
componentDidMount() {
this.scrollToMyRef();
}
// Render method. Note, that `div` element got `ref`.
render() {
return (
<div ref={this.myRef}>My component</div>
)
}
}
Utilisez la composition de fonction pour masquer les détails de l'implémentation
useScroll hook
Le crochet useScroll suivant masque les détails de l’implémentation dom et fournit une API simple.
const useScroll = () => {
const htmlElRef = useRef(null)
const executeScroll = () => {
window.scrollTo(0, htmlElRef.current.offsetTop)
}
return [executeScroll, htmlElRef]
}
Ensuite, vous pouvez facilement faire défiler vos composants fonctionnels.
const ScrollDemo = () => {
const [executeScroll, elementToScrollRef] = useScroll()
return (
<>
<div ref={elementToScrollRef}>I wanna be seen</div>
<button onClick={executeScroll}> Click to scroll </button>
</>
)
}
Cliquez ici pour une démo complète sur StackBlitz
useizeScroll
La fonction de composition pourrait également être utilisée dans les composants de classe.
const utilizeScroll = () => {
const htmlElRef = React.createRef()
const executeScroll = () => {
window.scrollTo(0, htmlElRef.current.offsetTop)
}
return {executeScroll, htmlElRef}
}
Puis utilisez-le dans n'importe quel composant de classe
class ScrollDemo extends Component {
constructor(){
this.elScroll = utilizeScroll()
}
render(){
return (
<>
<div ref={this.elScroll.htmlElRef}>I wanna be seen</div>
<button onClick={this.elScroll.executeScroll} >Click to scroll </button>
</>
)
}
}
Cliquez ici pour une démo complète sur StackBlitz
<div onScrollCapture={() => this._onScrollEvent()}></div>
_onScrollEvent = (e)=>{
const top = e.nativeEvent.target.scrollTop;
console.log(top);
}