我尝试通过redux使用异步数据使用reactjs为div设置动画,但我不清楚何时可以在状态loaded
上引用虚拟dom。
在我的情况下,我有一个id为header
的div,我希望在填充数据时按下容器。
如果我尝试使用componentDidMount而不是Cannot read property 'style' of undefined
,因为componentDidMount仍然具有对加载容器的引用
class HomePage extends React.Component {
constructor(props) {
super(props);
this.state = {
sliderLength: null
}
}
componentDidMount() {
this.props.actions.getSlides()
if(this.header) {
setTimeout(function() {
this.header.style.bottom = -(this.header.clientHeight - 40) + 'px';
}, 2000);
}
//header.style.bottom = -pushBottom+'px';
}
componentWillReceiveProps(nextProps) {
let {loaded} = nextProps
if(loaded === true ) {
this.animateHeader()
}
}
animateHeader() {
}
componentWillMount() {
const {slides} = this.props;
this.setState({
sliderLength: slides.length,
slides: slides
});
}
render() {
const {slides, post, loaded} = this.props;
if(loaded ===true ) {
let sliderTeaser = _.map(slides, function (slide) {
if(slide.status === 'publish') {
return <Link key={slide.id} to={'portfolio/' + slide.slug}><img key={slide.id} className="Img__Teaser" src={slide.featured_image_url.full} /></Link>
}
});
let about = _.map(post, function (data) {
return data.content.rendered;
})
return (
<div className="homePage">
<Slider columns={1} autoplay={true} post={post} slides={slides} />
<div id="header" ref={ (header) => this.header = header}>
<div className="title">Title</div>
<div className="text-content">
<div dangerouslySetInnerHTML={createMarkup(about)}/>
</div>
<div className="sliderTeaser">
{sliderTeaser}
</div>
<div className="columns">
<div className="column"></div>
<div className="column"></div>
<div className="column"></div>
</div>
</div>
<div id="bgHover"></div>
</div>
);
} else {
return <div>...Loading</div>
}
}
}
function mapStateToProps(state) {
return {
slides: state.slides,
post: state.post,
loaded: state.loaded
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(slidesActions, dispatch)
};
}
function createMarkup(markup) {
return {__html: markup};
}
export default connect(mapStateToProps, mapDispatchToProps)(HomePage);
我如何处理这种情况?
在我找到解决方案之间但不确定是否是正确的解决方法
componentDidUpdate() {
if(this.header) {
setTimeout(function() {
this.header.style.bottom = -(this.header.clientHeight - 35) + 'px';
}, 2000);
}
}
答案 0 :(得分:0)
如果您尝试为div设置动画,为什么要尝试通过this.header
访问它,只需使用javaScript的普通旧document.getElementById('header')
,然后就可以使用div。< / p>
答案 1 :(得分:0)
一般情况下,尽量避免使用ref
。如果你是React的新手,这一点尤其困难,但经过一些培训,你会发现自己并不需要它。
修改样式的问题就是当组件再次渲染时,您的更改将被覆盖。
我会创建一个新的state
属性,比如state.isHeaderOpen
。在render
方法中,您将根据此标题的值来不同地呈现标题,例如:
render () {
const {isHeaderOpen} = this.state
return (
<header style={{bottom: isHeaderOpen ? 0 : 'calc(100% - 40px)'}}>
)
}
这里我使用带有百分比值的calc
来获取标题的完整高度。
接下来,在您的componentDidMount
中只需更新状态:
componentDidMount () {
setTimeout(() => this.setState({isHeaderOpen: false}), 2000);
}
通过这种方式,组件将再次渲染,但具有更新的样式。
另一种方法是检查数据是否已加载,而不是创建新的state
值。例如,假设您要加载一个用户列表,请在render
中编写const isHeaderOpen = this.state.users != null
。