উত্তর:
তুষার যেমন উল্লেখ করেছেন, আপনি আপনার চ্যাটের নীচে একটি ডামি ডিভ রাখতে পারেন:
render () {
return (
<div>
<div className="MessageContainer" >
<div className="MessagesList">
{this.renderMessages()}
</div>
<div style={{ float:"left", clear: "both" }}
ref={(el) => { this.messagesEnd = el; }}>
</div>
</div>
</div>
);
}
এবং তারপরে এটিতে স্ক্রোল করুন যখনই আপনার উপাদানটি আপডেট হবে (যেমন নতুন বার্তা যুক্ত হওয়ার সাথে সাথে রাষ্ট্র আপডেট করা হবে):
scrollToBottom = () => {
this.messagesEnd.scrollIntoView({ behavior: "smooth" });
}
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}
আমি এখানে স্ট্যান্ডার্ড এলিমেন্ট.স্ক্রোলআইন্টিভিউ পদ্ধতিটি ব্যবহার করছি ।
this.messagesEnd.scrollIntoView()আমার জন্য ভাল কাজ করে। ব্যবহার করার দরকার নেই findDOMNode()।
scrollToBottom(){this.scrollBottom.scrollIntoView({ behavior: 'smooth' })}এটি আরও নতুন সংস্করণে কাজ করতে ফাংশন পরিবর্তন করেছে
আমি কেবল নতুন React.createRef() পদ্ধতির সাথে মেলে উত্তরটি আপডেট করতে চাই , তবে এটি মূলত একই, কেবল currentতৈরি রেফের মধ্যে থাকা সম্পত্তিটি মনে রাখবেন :
class Messages extends React.Component {
const messagesEndRef = React.createRef()
componentDidMount () {
this.scrollToBottom()
}
componentDidUpdate () {
this.scrollToBottom()
}
scrollToBottom = () => {
this.messagesEnd.current.scrollIntoView({ behavior: 'smooth' })
}
render () {
const { messages } = this.props
return (
<div>
{messages.map(message => <Message key={message.id} {...message} />)}
<div ref={this.messagesEndRef} />
</div>
)
}
}
হালনাগাদ:
এখন যে হুকগুলি উপলভ্য রয়েছে, আমি উত্তরগুলি useRefএবং useEffectহুকের ব্যবহার যুক্ত করার জন্য আপডেটটি আপডেট করছি , যাদু করার জন্য আসল জিনিসটি (রিএ্যাক্ট রেফার্স এবং scrollIntoViewডোম পদ্ধতি) একই রয়ে গেছে:
import React, { useEffect, useRef } from 'react'
const Messages = ({ messages }) => {
const messagesEndRef = useRef(null)
const scrollToBottom = () => {
messagesEndRef.current.scrollIntoView({ behavior: "smooth" })
}
useEffect(scrollToBottom, [messages]);
return (
<div>
{messages.map(message => <Message key={message.id} {...message} />)}
<div ref={messagesEndRef} />
</div>
)
}
আপনি যদি https://codesandbox.io/s/scroltobottomexample-f90lz আচরণটি পরীক্ষা করতে চান তবে একটি (খুব প্রাথমিক) কোডস্যান্ডবক্সও তৈরি করেছেন
this.messagesEnd.currentসর্বদা উপস্থিত থাকে। তবুও এটি লক্ষ্য করা গুরুত্বপূর্ণ যে this.messagesEnd.currentপ্রথম রেন্ডারের আগে কল করার ফলে আপনি চিহ্নিত হওয়া ত্রুটি ঘটবে। Thnx।
this.messagesEndscrollTo পদ্ধতিতে আপনার প্রথম উদাহরণে?
useEffectপদ্ধতি প্রয়োজন সঙ্গে স্থাপন করা হবে () => {scrollToBottom()}। যাইহোক ধন্যবাদ অনেক
ব্যবহার করবেন না findDOMNode
class MyComponent extends Component {
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}
scrollToBottom() {
this.el.scrollIntoView({ behavior: 'smooth' });
}
render() {
return <div ref={el => { this.el = el; }} />
}
}
import React, { useRef, useEffect } from 'react';
const MyComponent = () => {
const divRref = useRef(null);
useEffect(() => {
divRef.current.scrollIntoView({ behavior: 'smooth' });
});
return <div ref={divRef} />;
}
behavior(সম্পাদনা করতে পারে না কারণ "সম্পাদনাগুলি কমপক্ষে 6 টি অক্ষর হতে হবে", দীর্ঘশ্বাস)।
scrollIntoViewসঙ্গে smoothমুহূর্তে খুব খারাপ।
@ এলিটমেন্টকে ধন্যবাদ
আমাদের ব্যবহার এড়ানো উচিত findDOMNode, আমরা refsউপাদানগুলি ট্র্যাক রাখতে ব্যবহার করতে পারি
render() {
...
return (
<div>
<div
className="MessageList"
ref={(div) => {
this.messageList = div;
}}
>
{ messageListContent }
</div>
</div>
);
}
scrollToBottom() {
const scrollHeight = this.messageList.scrollHeight;
const height = this.messageList.clientHeight;
const maxScrollTop = scrollHeight - height;
this.messageList.scrollTop = maxScrollTop > 0 ? maxScrollTop : 0;
}
componentDidUpdate() {
this.scrollToBottom();
}
রেফারেন্স:
refউপাদানগুলির উপর নজর রাখতে আপনি ব্যবহার করতে পারেন ।
যদি আপনি কোনও refপৃথক উপাদানটির (সর্বশেষটি) সেট করার কোনও উপায় জানেন তবে দয়া করে পোস্ট করুন!
আমার জন্য আমি যা কাজ করেছিলাম তা এখানে:
class ChatContainer extends React.Component {
render() {
const {
messages
} = this.props;
var messageBubbles = messages.map((message, idx) => (
<MessageBubble
key={message.id}
message={message.body}
ref={(ref) => this['_div' + idx] = ref}
/>
));
return (
<div>
{messageBubbles}
</div>
);
}
componentDidMount() {
this.handleResize();
// Scroll to the bottom on initialization
var len = this.props.messages.length - 1;
const node = ReactDOM.findDOMNode(this['_div' + len]);
if (node) {
node.scrollIntoView();
}
}
componentDidUpdate() {
// Scroll as new elements come along
var len = this.props.messages.length - 1;
const node = ReactDOM.findDOMNode(this['_div' + len]);
if (node) {
node.scrollIntoView();
}
}
}
আপনার বার্তাগুলির ধারক উল্লেখ করুন।
<div ref={(el) => { this.messagesContainer = el; }}> YOUR MESSAGES </div>আপনার বার্তাগুলির ধারকটি আবিষ্কার করুন এবং এর scrollTopবৈশিষ্ট্যটি সমান করুন scrollHeight:
scrollToBottom = () => {
const messagesContainer = ReactDOM.findDOMNode(this.messagesContainer);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
};উপর পদ্ধতি উপরে আহ্বান componentDidMountএবং componentDidUpdate।
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}এইভাবে আমি আমার কোডটিতে এটি ব্যবহার করছি:
export default class StoryView extends Component {
constructor(props) {
super(props);
this.scrollToBottom = this.scrollToBottom.bind(this);
}
scrollToBottom = () => {
const messagesContainer = ReactDOM.findDOMNode(this.messagesContainer);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
};
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}
render() {
return (
<div>
<Grid className="storyView">
<Row>
<div className="codeView">
<Col md={8} mdOffset={2}>
<div ref={(el) => { this.messagesContainer = el; }}
className="chat">
{
this.props.messages.map(function (message, i) {
return (
<div key={i}>
<div className="bubble" >
{message.body}
</div>
</div>
);
}, this)
}
</div>
</Col>
</div>
</Row>
</Grid>
</div>
);
}
}
প্রতিক্রিয়া-স্ক্রোলযোগ্য-ফিড স্বয়ংক্রিয়ভাবে সর্বশেষ উপাদানটিতে স্ক্রোল করে যদি ব্যবহারকারী ইতিমধ্যে স্ক্রোলযোগ্য বিভাগের নীচে থাকে। অন্যথায় এটি ব্যবহারকারীকে একই পজিশনে রেখে যাবে। আমি মনে করি এটি চ্যাট উপাদানগুলির জন্য বেশ দরকারী :)
আমি মনে করি যে এখানে অন্যান্য উত্তরগুলি স্ক্রোলবারটি যেখানেই ছিল না কেন প্রতিবারই স্ক্রোলকে বাধ্য করবে। অন্য সমস্যাটি scrollIntoViewহ'ল এটি যদি আপনার স্ক্রোলযোগ্য ডিভি না হয় তবে এটি পুরো পৃষ্ঠাটি স্ক্রোল করবে।
এটি এর মতো ব্যবহার করা যেতে পারে:
import * as React from 'react'
import ScrollableFeed from 'react-scrollable-feed'
class App extends React.Component {
render() {
const messages = ['Item 1', 'Item 2'];
return (
<ScrollableFeed>
{messages.map((message, i) => <div key={i}>{message}</div>)}
</ScrollableFeed>
);
}
}
সুনির্দিষ্ট heightবা সাথে একটি মোড়কের উপাদান রয়েছে তা নিশ্চিত করুনmax-height
দাবি অস্বীকার: আমি প্যাকেজের মালিক
আমি বার্তাগুলির শেষে একটি খালি উপাদান তৈরি করেছি এবং সেই উপাদানটিতে স্ক্রোল করেছি। রেফার ট্র্যাক রাখার দরকার নেই।
আপনি যদি প্রতিক্রিয়া হুক্স দিয়ে এটি করতে চান তবে এই পদ্ধতিটি অনুসরণ করা যেতে পারে। একটি ডামি ডিভের জন্য আড্ডার নীচে রাখা হয়েছে। এখানে ব্যবহারকারীর হুক ব্যবহৃত হয়।
হুকস এপিআই রেফারেন্স: https://reactjs.org/docs/hooks-references.html#useref
import React, { useEffect, useRef } from 'react';
const ChatView = ({ ...props }) => {
const el = useRef(null);
useEffect(() => {
el.current.scrollIntoView({ block: 'end', behavior: 'smooth' });
});
return (
<div>
<div className="MessageContainer" >
<div className="MessagesList">
{this.renderMessages()}
</div>
<div id={'el'} ref={el}>
</div>
</div>
</div>
);
}
আমার ReactJS সংস্করণ: 16.12.0
এইচটিএমএলrender() ফাংশন ভিতরে কাঠামো
render()
return(
<body>
<div ref="messageList">
<div>Message 1</div>
<div>Message 2</div>
<div>Message 3</div>
</div>
</body>
)
)
scrollToBottom()ফাংশন যা উপাদান রেফারেন্স পাবেন। এবং scrollIntoView()ফাংশন অনুযায়ী স্ক্রোল ।
scrollToBottom = () => {
const { messageList } = this.refs;
messageList.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
}
এবং উপরের ফাংশন ভিতরে কল componentDidMount()এবংcomponentDidUpdate()
ডেভেলপার.মোজিলা.অর্গ.এর সম্পর্কে আরও তথ্যের Element.scrollIntoView()জন্য
কাজের উদাহরণ:
ভিউটিতে scrollIntoViewকোনও উপাদান দৃশ্যমান করতে আপনি ডোম পদ্ধতিটি ব্যবহার করতে পারেন ।
এই জন্য, উপাদানটি রেন্ডার করার সময় কেবল refঅ্যাট্রিবিউট ব্যবহার করে DOM উপাদানটির জন্য একটি রেফারেন্স আইডি দিন । তারপর পদ্ধতি ব্যবহার scrollIntoViewউপর componentDidMountজীবনচক্র। আমি এই সমাধানের জন্য একটি কার্যকারী নমুনা কোড রাখছি। নিম্নলিখিত বার্তাটি প্রাপ্ত হওয়ার সময় নীচে একটি উপাদান রেন্ডারিং হয়। এই উপাদানটি সরবরাহ করার জন্য আপনার কোড / পদ্ধতিগুলি লিখতে হবে।
class ChatMessage extends Component {
scrollToBottom = (ref) => {
this.refs[ref].scrollIntoView({ behavior: "smooth" });
}
componentDidMount() {
this.scrollToBottom(this.props.message.MessageId);
}
render() {
return(
<div ref={this.props.message.MessageId}>
<div>Message content here...</div>
</div>
);
}
}
এখানে this.props.message.MessageIdনির্দিষ্ট চ্যাট বার্তার অনন্য আইডি হিসাবে দেওয়া হয়েছে passedprops
import React, {Component} from 'react';
export default class ChatOutPut extends Component {
constructor(props) {
super(props);
this.state = {
messages: props.chatmessages
};
}
componentDidUpdate = (previousProps, previousState) => {
if (this.refs.chatoutput != null) {
this.refs.chatoutput.scrollTop = this.refs.chatoutput.scrollHeight;
}
}
renderMessage(data) {
return (
<div key={data.key}>
{data.message}
</div>
);
}
render() {
return (
<div ref='chatoutput' className={classes.chatoutputcontainer}>
{this.state.messages.map(this.renderMessage, this)}
</div>
);
}
}
আমি নিম্নলিখিত পদ্ধতিতে এটি করতে পছন্দ করি।
componentDidUpdate(prevProps, prevState){
this.scrollToBottom();
}
scrollToBottom() {
const {thing} = this.refs;
thing.scrollTop = thing.scrollHeight - thing.clientHeight;
}
render(){
return(
<div ref={`thing`}>
<ManyThings things={}>
</div>
)
}
তার উত্তরের জন্য আপনাকে 'মেটেকারমিট' ধন্যবাদ জানাই, তবে আমি মনে করি আমরা এটিকে কিছুটা আরও উন্নত করতে পারি, নীচে স্ক্রোল করার জন্য আমাদের এটি ব্যবহার করা উচিত:
scrollToBottom = () => {
this.messagesEnd.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" });
}
তবে আপনি যদি শীর্ষে স্ক্রোল করতে চান তবে আপনার এটি ব্যবহার করা উচিত:
scrollToTop = () => {
this.messagesEnd.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
}
এবং এই কোডগুলি সাধারণ:
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}
render () {
return (
<div>
<div className="MessageContainer" >
<div className="MessagesList">
{this.renderMessages()}
</div>
<div style={{ float:"left", clear: "both" }}
ref={(el) => { this.messagesEnd = el; }}>
</div>
</div>
</div>
);
}
অন্য বিকল্প হিসাবে এটি প্রতিক্রিয়াশীল স্ক্রোল উপাদানটি দেখার মতো।
ব্যবহার React.createRef()
class MessageBox extends Component {
constructor(props) {
super(props)
this.boxRef = React.createRef()
}
scrollToBottom = () => {
this.boxRef.current.scrollTop = this.boxRef.current.scrollHeight
}
componentDidUpdate = () => {
this.scrollToBottom()
}
render() {
return (
<div ref={this.boxRef}></div>
)
}
}
আপনি টাইপস্ক্রিপ্টে এটি কীভাবে সমাধান করবেন (কোনও লক্ষ্যযুক্ত উপাদানের রেফ ব্যবহার করে যেখানে আপনি স্ক্রোল করছেন):
class Chat extends Component <TextChatPropsType, TextChatStateType> {
private scrollTarget = React.createRef<HTMLDivElement>();
componentDidMount() {
this.scrollToBottom();//scroll to bottom on mount
}
componentDidUpdate() {
this.scrollToBottom();//scroll to bottom when new message was added
}
scrollToBottom = () => {
const node: HTMLDivElement | null = this.scrollTarget.current; //get the element via ref
if (node) { //current ref can be null, so we have to check
node.scrollIntoView({behavior: 'smooth'}); //scroll to the targeted element
}
};
render <div>
{message.map((m: Message) => <ChatMessage key={`chat--${m.id}`} message={m}/>}
<div ref={this.scrollTarget} data-explanation="This is where we scroll to"></div>
</div>
}
প্রতিক্রিয়া এবং টাইপস্ক্রিপ্ট সহ রেফ ব্যবহার সম্পর্কে আরও তথ্যের জন্য আপনি একটি দুর্দান্ত নিবন্ধটি এখানে পেতে পারেন ।
সম্পূর্ণ সংস্করণ (টাইপস্ক্রিপ্ট):
import * as React from 'react'
export class DivWithScrollHere extends React.Component<any, any> {
loading:any = React.createRef();
componentDidMount() {
this.loading.scrollIntoView(false);
}
render() {
return (
<div ref={e => { this.loading = e; }}> <LoadingTile /> </div>
)
}
}
Property 'scrollIntoView' does not exist on type 'RefObject<unknown>'. এবং Type 'HTMLDivElement | null' is not assignable to type 'RefObject<unknown>'. Type 'null' is not assignable to type 'RefObject<unknown>'. তাই ...