我试图使用React组件的状态来控制文本区域的滚动位置,但是当我调用setState()
时它不会移动。
在此示例中,单击链接应滚动到文本区域的顶部,但不会移动。使用滚动条滚动可以记录位置,并且字段会移动。单击链接会将消息写入控制台,但滚动位置不会移动。我将这种方法基于ReactJS文档中所述的controlled components。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {scrollTop: 0};
this.handleScroll = this.handleScroll.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleScroll() {
let scrollTop = this.refs.content.scrollTop;
console.log(scrollTop);
this.setState({scrollTop: scrollTop});
}
handleClick(e) {
e.preventDefault();
console.log('Clicked.');
this.setState({scrollTop: 0});
}
render() {
let text = 'a\n\nb\n\nc\n\nd\n\ne\n\nf\n\ng';
return <p><textarea
ref="content"
value={text}
rows="10"
cols="30"
scrollTop={this.state.scrollTop}
onScroll={this.handleScroll}/>
<a href="#" onClick={this.handleClick}>
Scroll to top
</a></p>;
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
);
.as-console-wrapper { max-height: 10% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
我可以通过使用ref并设置其scrollTop
来控制滚动位置,但是我想通过组件状态或组件属性来控制滚动位置。 (最终,我想同步两个文本区域的滚动。)我也尝试使用react-scroll-sync
library,但是它不适用于表格单元格。
下面是一个使用ref及其scrollTop
控制位置的示例:
class App extends React.Component {
constructor(props) {
super(props);
this.handleScroll = this.handleScroll.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleScroll() {
let scrollTop = this.refs.content.scrollTop;
console.log(scrollTop);
}
handleClick(e) {
e.preventDefault();
console.log('Clicked.');
this.refs.content.scrollTop = 0;
}
render() {
let text = 'a\n\nb\n\nc\n\nd\n\ne\n\nf\n\ng';
return <p><textarea
ref="content"
value={text}
rows="10"
cols="30"
onScroll={this.handleScroll}/>
<a href="#" onClick={this.handleClick}>
Scroll to top
</a></p>;
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
);
.as-console-wrapper { max-height: 10% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
答案 0 :(得分:1)
汤米·梅(Tommy May)在评论中解释说scrollTop
不是HTML属性,因此我无法将其直接链接到组件状态或属性。但是,我发现componentDidUpdate()
method可用于处理状态或属性的更改。
这是使用componentDidUpdate()
的更新示例:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {scrollTop: 0};
this.content = React.createRef();
this.handleScroll = this.handleScroll.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleScroll() {
let scrollTop = this.content.current.scrollTop;
console.log(scrollTop);
this.setState({scrollTop: scrollTop});
}
handleClick(e) {
e.preventDefault();
console.log('Clicked.');
this.setState({scrollTop: 0});
}
componentDidUpdate() {
this.content.current.scrollTop = this.state.scrollTop;
}
render() {
let text = 'a\n\nb\n\nc\n\nd\n\ne\n\nf\n\ng';
return <p><textarea
ref={this.content}
value={text}
rows="10"
cols="30"
onScroll={this.handleScroll}/>
<a href="#" onClick={this.handleClick}>
Scroll to top
</a></p>;
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
);
.as-console-wrapper { max-height: 10% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
这在此示例中并不是特别有用,但是当您要使用属性而不是本地状态时,它很有用,例如我出于同步滚动的最初目标发布的this answer。