我只是学习反应,并希望实现一个功能: A,B都是组件,如果是A滚动,则B滚动
以下是我的代码
<A onScroll="handleScroll"></A>
//what i write now
handleScroll: function(event){
var target = event.nativeEvent.target;
//do something to change scrollTop value
target.scrollTop += 1;
// it looks the same as not use react
document.getElementById(B).scrollTop = target.scrollTop;
}
但实际上我想要这样的代码
//what i want
<A scrollTop={this.props.scrollSeed}></A>
<B scrollTop={this.props.scrollSeed}></B>
//...
handleScroll(){
this.setState({scrollSeed: ++this.state.scrollSeed})
}
类似于input
<input value="this.props.value"/>
<input value="this.props.value"/>
<input ref='c' onChange={handleChange}>
//...
handleChange: function() {
// enter some code in c and then render in a and b automatically
}
换句话说,我想要一些属性,比如scrollTop
(不同
表单<input value={}>
,因为<A scrollTop={}>
不起作用),与某个州绑定,以便我可以使用setState
,他们会自行更新。
答案 0 :(得分:11)
有许多模式可以实现这一目标。这sample是我提出的让你起步的原因。
首先创建一个组件类,它具有一个用于滚动效果的超大元素。拖动滚动条时,此组件会调用其handleScroll
React属性以通知其父组件,其值为scrollTop
。
var Elem = React.createClass({
render() {
return (
<div ref="elem"
onScroll={ this.onScroll }
style={{ width: "100px", height: "100px", overflow: "scroll" }}>
<div style={{ width: "100%", height: "200%" }}>Hello!</div>
</div>
);
},
componentDidUpdate() {
this.refs.elem.scrollTop = this.props.scrollTop;
},
onScroll() {
this.props.handleScroll( this.refs.elem.scrollTop );
}
});
父组件(又称包装器)将滚动顶部值保持在其状态。它的handleScroll
作为回调传递给子组件。子元素上的任何滚动都会触发回调,设置状态,导致重绘,并更新子组件。
var Wrapper = React.createClass({
getInitialState() {
return {
scrollTop: 0
}
},
render() {
return (
<div>
<Elem scrollTop={ this.state.scrollTop } handleScroll={ this.handleScroll } />
<Elem scrollTop={ this.state.scrollTop } handleScroll={ this.handleScroll } />
</div>
);
},
handleScroll( scrollTop ) {
this.setState({ scrollTop });
}
});
渲染包装器,假设现有<div id="container"></div>
。
ReactDOM.render(
<Wrapper />,
document.getElementById('container')
);
答案 1 :(得分:2)
this.refs已弃用。使用reactjs.org/docs/refs-and-the-dom.html#creating-refs
import React from 'react';
class SomeComponent extends React.Component {
constructor(props) {
super(props);
this.resultsDiv = React.createRef();
}
someFunction(){
this.resultsDiv.current.scrollTop = 0;
}
render() {
return (
<div ref={this.resultsDiv} />
);
}
}
export default SomeComponent;
答案 2 :(得分:1)
首先,解决方法:
const resetScrollEffect = ({ element }) => {
element.current.getScrollableNode().children[0].scrollTop = 0
}
const Table = props => {
const tableRef = useRef(null)
useEffect(() => resetScrollEffect({ element: tableRef }), [])
return (
<Component>
<FlatList
ref={someRef}
/>
</Component>
)
}
第二,一些解释:
Idk,您到达这里的原因是什么,但是我在FlatList中使用了flex-direction: column-reverse
(这是元素列表)。我需要此属性用于z-index
。但是,浏览器将此类元素(表格,聊天等)的滚动位置设置为末尾-这可能很有用,但在我的情况下不需要。
此外,示例使用React Hooks显示,但是您可以使用 old 更传统的定义引用的方式
答案 3 :(得分:0)
这是Season's answer的更新版本,其中包括可运行的代码段。它对creating refs使用推荐的方法。
class Editor extends React.Component {
constructor(props) {
super(props);
this.content = React.createRef();
this.handleScroll = this.handleScroll.bind(this);
}
componentDidUpdate() {
this.content.current.scrollTop = this.props.scrollTop;
}
handleScroll() {
this.props.onScroll( this.content.current.scrollTop );
}
render() {
let text = 'a\n\nb\n\nc\n\nd\n\ne\n\nf\n\ng';
return <textarea
ref={this.content}
value={text}
rows="10"
cols="30"
onScroll={this.handleScroll}/>;
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {scrollTop: 0};
this.handleScroll = this.handleScroll.bind(this);
}
handleScroll(scrollTop) {
this.setState({scrollTop: scrollTop});
}
render() {
return <table><tbody>
<tr><th>Foo</th><th>Bar</th></tr>
<tr>
<td><Editor
scrollTop={this.state.scrollTop}
onScroll={this.handleScroll}/></td>
<td><Editor
scrollTop={this.state.scrollTop}
onScroll={this.handleScroll}/></td>
</tr>
</tbody></table>;
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
);
<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>