ReactJS 等待道具加载以避免页面崩溃的正确方法是什么?
ReactJS what is the proper way to wait for prop to load to avoid crashing my page?
全部,
我正在为自己建立一个本地股票网站。目前我有一家商店与我的 tomcat 实例通信以获取股票市场数据,这完美无缺。
在我的前端,我试图显示我的数据,但有时它可以工作,有时它不工作并且我得到一个“这个子道具不存在”所以这就是我实现的:
try{
cellRend = this.cellRenderer;
columnLen = this.props.selectedStock.Revenue.length;
this.state.isLoading = false
}catch(error){
cellRend = this.cellRendererEmpty;
columnLen = 10;
}
if (this.state.isLoading === true){
return <div>Loading!</div>
}
其中 cellRenderer 是我的 table,cellRendererEmpty 是空的 table。
这种作品有时会显示正在加载!永远。所以我的问题是等待道具的正确方法是什么?
这是我的完整代码:
const dispatchToProps = dispatch => {
return{
getSelStock: (stockId) => dispatch(stockActions.getSelStock(stockId))
};
}
class stockPage extends React.Component{
constructor(props) {
super(props);
this.state = {
columnLen:10,
data:null,
isLoading:true
}
console.log(this.props.isLoading)
this.cellRenderer = this.cellRenderer.bind(this);
this.render = this.render.bind(this);
}
cellRenderer({ columnIndex, key, rowIndex, style }) {
return (
<div className={"app"} key={key} style={style}>
<span></span>
{rowIndex === 0 ? (`${this.props.selectedStock.Revenue[columnIndex].date}`) : (
<span>{`${this.props.selectedStock.Revenue[columnIndex].value}`}</span>
)}
</div>
);
}
cellRendererEmpty({ columnIndex, key, rowIndex, style }) {
return (
<div className={"app"} key={key} style={style}>
{rowIndex === 0 ? (`${columnIndex}`) : (
<span>{`${columnIndex}`}</span>
)}
</div>
);
}
render() {
var cellRend, columnLen
console.log("Hey")
this.props.getSelStock(this.props.match.params.stockId);
try{
cellRend = this.cellRenderer;
columnLen = this.props.selectedStock.Revenue.length;
this.state.isLoading = false
}catch(error){
cellRend = this.cellRendererEmpty;
columnLen = 10;
}
if (this.state.isLoading === true){
return <div>Loading!</div>
}
return(
<div>
<h1>{this.props.match.params.stockId}</h1>
<AutoSizer disableHeight>
{({ width }) => (
<MultiGrid
cellRenderer={cellRend}
columnWidth={125}
columnCount={this.state.columnLen}
enableFixedColumnScroll ={1}
enableFixedRowScroll ={1}
fixedColumnCount
fixedRowCount
height={300}
rowHeight={70}
rowCount={2}
style={STYLE}
styleBottomLeftGrid={STYLE_BOTTOM_LEFT_GRID}
styleTopLeftGrid={STYLE_TOP_LEFT_GRID}
styleTopRightGrid={STYLE_TOP_RIGHT_GRID}
width={width}
hideTopRightGridScrollbar
hideBottomLeftGridScrollbar
hideBottomRightGridScrollbar
/>
)}
</AutoSizer>
</div>
)
}
}
export default connect(mapStateToProps, dispatchToProps)(stockPage);
根据您的标题,我假设当您的页面加载时,您正在获取数据然后在页面中使用该数据。但是,在初始加载期间以及您的提取仍在进行中时,您的数据仍然为空并且您的应用程序将崩溃,因为代码期望数据具有它需要使用的值...
您可以做的是在获取数据时,先不显示页面的其余部分(即,您可以只显示一个巨大的微调器 gif),然后在获取完成后更新 isLoading 状态。 .. 或者您可以为数据设置一个初始值,这样页面就不会在加载时崩溃...
编辑:
所以使用 React 生命周期根据你的评论解决了你的问题......无论如何只是想补充一点你可能想要使用 async/await 而不是 setTimeout 就像你在你的评论中所做的那样......这就是代码可能看起来像 async/await 在生命周期中...
componentDidMount() {
const fetchData = async () {
await this.props.getSelStock() // your dispatch
// the state you want to update once the dispatch is done
this.setState({isLoading: false})
}
fetchData();
}
全部,
我正在为自己建立一个本地股票网站。目前我有一家商店与我的 tomcat 实例通信以获取股票市场数据,这完美无缺。
在我的前端,我试图显示我的数据,但有时它可以工作,有时它不工作并且我得到一个“这个子道具不存在”所以这就是我实现的:
try{
cellRend = this.cellRenderer;
columnLen = this.props.selectedStock.Revenue.length;
this.state.isLoading = false
}catch(error){
cellRend = this.cellRendererEmpty;
columnLen = 10;
}
if (this.state.isLoading === true){
return <div>Loading!</div>
}
其中 cellRenderer 是我的 table,cellRendererEmpty 是空的 table。
这种作品有时会显示正在加载!永远。所以我的问题是等待道具的正确方法是什么?
这是我的完整代码:
const dispatchToProps = dispatch => {
return{
getSelStock: (stockId) => dispatch(stockActions.getSelStock(stockId))
};
}
class stockPage extends React.Component{
constructor(props) {
super(props);
this.state = {
columnLen:10,
data:null,
isLoading:true
}
console.log(this.props.isLoading)
this.cellRenderer = this.cellRenderer.bind(this);
this.render = this.render.bind(this);
}
cellRenderer({ columnIndex, key, rowIndex, style }) {
return (
<div className={"app"} key={key} style={style}>
<span></span>
{rowIndex === 0 ? (`${this.props.selectedStock.Revenue[columnIndex].date}`) : (
<span>{`${this.props.selectedStock.Revenue[columnIndex].value}`}</span>
)}
</div>
);
}
cellRendererEmpty({ columnIndex, key, rowIndex, style }) {
return (
<div className={"app"} key={key} style={style}>
{rowIndex === 0 ? (`${columnIndex}`) : (
<span>{`${columnIndex}`}</span>
)}
</div>
);
}
render() {
var cellRend, columnLen
console.log("Hey")
this.props.getSelStock(this.props.match.params.stockId);
try{
cellRend = this.cellRenderer;
columnLen = this.props.selectedStock.Revenue.length;
this.state.isLoading = false
}catch(error){
cellRend = this.cellRendererEmpty;
columnLen = 10;
}
if (this.state.isLoading === true){
return <div>Loading!</div>
}
return(
<div>
<h1>{this.props.match.params.stockId}</h1>
<AutoSizer disableHeight>
{({ width }) => (
<MultiGrid
cellRenderer={cellRend}
columnWidth={125}
columnCount={this.state.columnLen}
enableFixedColumnScroll ={1}
enableFixedRowScroll ={1}
fixedColumnCount
fixedRowCount
height={300}
rowHeight={70}
rowCount={2}
style={STYLE}
styleBottomLeftGrid={STYLE_BOTTOM_LEFT_GRID}
styleTopLeftGrid={STYLE_TOP_LEFT_GRID}
styleTopRightGrid={STYLE_TOP_RIGHT_GRID}
width={width}
hideTopRightGridScrollbar
hideBottomLeftGridScrollbar
hideBottomRightGridScrollbar
/>
)}
</AutoSizer>
</div>
)
}
}
export default connect(mapStateToProps, dispatchToProps)(stockPage);
根据您的标题,我假设当您的页面加载时,您正在获取数据然后在页面中使用该数据。但是,在初始加载期间以及您的提取仍在进行中时,您的数据仍然为空并且您的应用程序将崩溃,因为代码期望数据具有它需要使用的值...
您可以做的是在获取数据时,先不显示页面的其余部分(即,您可以只显示一个巨大的微调器 gif),然后在获取完成后更新 isLoading 状态。 .. 或者您可以为数据设置一个初始值,这样页面就不会在加载时崩溃...
编辑: 所以使用 React 生命周期根据你的评论解决了你的问题......无论如何只是想补充一点你可能想要使用 async/await 而不是 setTimeout 就像你在你的评论中所做的那样......这就是代码可能看起来像 async/await 在生命周期中...
componentDidMount() {
const fetchData = async () {
await this.props.getSelStock() // your dispatch
// the state you want to update once the dispatch is done
this.setState({isLoading: false})
}
fetchData();
}