javascript - React JS 组件未在移动设备中完全呈现
问题描述
我有一个通过 heroku 部署的反应 JS 应用程序。在桌面浏览器上,我可以看到所有渲染的 reactJS 组件。但在移动设备上,我只能看到在设备尺寸内渲染的组件。
这是组件最初加载到移动设备上的时间。向下滚动时应该有更多卡片
没有更多的卡片可见,因为它们在最初加载时超出了视图高度。但是它们在那里-我可以向下滚动到底部,但看不到卡片
但是,如果我关闭/打开设备,或者打开其他应用程序并返回 safari,我可以神奇地看到设备高度内的卡片。
同样,卡片下方没有显示任何内容。如果我重复上面的步骤,我可以看到下面的卡片
这是 git repo 的链接。卡片的 Div 在“src/components/messages.js”中呈现
https://github.com/jessicakwak/hitmeup-client
import React, { Component } from "react";
import "./styles/Messages.css";
import "./styles/NewMessage.css";
import axios from "axios";
import Moment from "react-moment";
class Messages extends Component {
// Data
state = {
messages: [],
selected: this.props.selected,
wallOpen: false
};
componentDidMount() {
this.setState(
{
selected: this.props.selected,
wallOpen: this.props.wallOpen
}, //async function, so do stuffs after this happened
() => {
let config = {
headers: { Authorization: `Bearer ${localStorage.getItem("token")}` }
};
axios
.get(
`${process.env.REACT_APP_API}/messages?channel=${this.state.selected}`,
config
)
.then(res => {
res.data.reverse();
this.setState({ messages: res.data });
})
.catch(err => console.log(err));
this.forceUpdate();
}
);
}
componentWillReceiveProps(newProps) {
//when the props inherited from Chat changed from [] to something
this.setState(
{
selected: newProps.selected,
wallOpen: newProps.wallOpen
}, //async function, so do stuffs after this happened
() => {
let config = {
headers: { Authorization: `Bearer ${localStorage.getItem("token")}` }
};
axios
.get(
`${process.env.REACT_APP_API}/messages?channel=${this.state.selected}`,
config
)
.then(res => {
res.data.reverse();
this.setState({ messages: res.data });
})
.catch(err => console.log(err));
this.forceUpdate();
}
);
}
// Render
render() {
return (
<div id="messages">
<div id="content">
{this.state.messages.map(message => {
return (
<div className="message" key={message._id}>
<div
className="userImageMessage"
style={{
backgroundImage: `url(${message.user.image})`
}}
></div>
<div className="usrInfo">
<span className="user">{message.user.name}</span>
<span className="summaryText first">
{" "}
wants to meet up at{" "}
</span>
<span className="location">{message.location}</span>
<span className="summaryText"> on </span>
<span className="eventDate">
<Moment date={message.date} format="ll" />{" "}
</span>
<span> at </span>
<span className="eventTime">
<Moment date={message.date} format="LT" />
</span>
</div>
<div className="body">{message.text}</div>
<span className="date">
<Moment
date={message.createDate}
format="MMMM Do YYYY, h:mm:ss a"
/>
</span>
</div>
);
})}
</div>
</div>
);
}
}
export default Messages;
提前致谢!
解决方案
目前还不清楚问题到底是什么,但这些更新应该让您的组件代码处于更好的状态。
问题:
- 将 props 保存到 state 是一种反模式,只需从 props 中消费
setState
不打算“链接”多个同步状态更新,而是使用生命周期函数- 提供足够的初始状态,只取数据
componentDidMount
- 数据获取实际上只依赖于
props.selected
,因此无需先将其存储在状态中 componentWillReceiveProps
几乎不推荐使用,使用componentDidUpdate
forceUpdate
应该真的几乎从不需要
解决方案:
- 将数据提取分解为函数(相对于
setState
回调):DRY 原则 - 消费
props.selected
数据获取:单一事实来源 - 获取数据
componentDidMount
:使用生命周期函数 - 利用
componentDidUpdate
比较先前和当前props.selected
值并重新获取数据:使用生命周期函数
注意:我看不到如何wallOpen
使用,所以保留该行为
// Data
state = {
messages: [],
wallOpen: this.props.wallOpen, // just set initial wallopen from props
};
fetchMessages = () => {
const config = {
headers: { Authorization: `Bearer ${localStorage.getItem("token")}` }
};
axios
.get(
`${process.env.REACT_APP_API}/messages?channel=${this.props.selected}`,
config
)
.then(res => {
res.data.reverse();
this.setState({ messages: res.data });
})
.catch(err => console.log(err));
}
componentDidMount() {
this.fetchMessages();
}
componentDidUpdate(prevProps) {
const { selected, wallOpen } = this.props;
// if selected prop changed, refetch data
if (prevProps.selected !== selected) {
this.fetchMessages();
}
// if new wallOpen prop changed, store it
if (prevProps.wallOpen !== wallOpen) {
this.setState({ wallOpen });
}
}
推荐阅读
- angular - 角度找不到styles.sass
- laravel - 我使用 pm2 与 (*) 共享的 ViewComposer 执行队列作业而无需暂停
- c++ - 对向量使用 Push Back 功能时的分段错误
- google-app-engine - 为什么我的 Google App Engine 应用使用旧版本的 OpenSSL?
- json - 在 jq 中对 JSON 对象进行排序
- django - 构建提供 django 休息框架模型的可选反应日期字段的正确方法是什么?
- php - PHP SOAP - 给出不存在的 [HTTP] 内部服务器错误
- arrays - 将保存在数据库中的数组格式化为 laravel 中的刀片视图
- java - 从给定模式中选择 m 个不同对象的最快方法?
- android - LiveData + ViewModel + Room:公开查询返回的 LiveData 随时间变化(通过 fts 搜索)