我有一个组件(DatasetPage),它为所选图像渲染不同数据集的一些图像。这取决于在导航顶部栏上单击的选项卡。问题是我的情况中的一个数据集非常大,因此加载页面需要更多时间。如果我等到页面加载一切正常但是,如果我在reducer将属性传递给我的组件(ImageWithRelateds)之前单击另一个选项卡(另一个数据集),则新页面将加载另一个(最后一个)的信息数据集,尚未加载。
所以,我已经考虑过一个解决方案,当我有正在运行的加载时,它可以阻止导航栏的导航。但问题是这个加载的东西是在ImageWithRelateds.js组件中控制的,导航栏是从App.js控制的。所以我需要从App.js访问ImageWithRelateds.js的isLoading属性(我已经拥有),但我不知道该怎么做。我刚刚找到了从子级访问父属性但不向后访问的方法。如果你可以帮助我,或者只是提出另一个解决方案,我将非常感激。
App.js
import React, { Component } from 'react';
import { IndexLink } from 'react-router';
import '../styles/app.scss';
class App extends Component {
constructor(props){
super(props);
this.options = this.props.route.data;
}
renderContent(){
if(this.props.route.options) {
return(<div className="navbar-header nav">
<a className="navbar-brand" id="title" href="/" >
IMAGES TEST WEB
</a>
<li className="nav-item" key={`key-9999`}>
<IndexLink to='/home' className="nav-link active" href="#">HOME</IndexLink>
</li>
{this.props.route.options.map((opt,i)=>{
return this.returnOptions(opt,i);
})}
</div>
);
}
}
returnOptions(opt,i){
return(<li className="nav-item" key={`key-${i}`}>
<IndexLink to={opt.link} className="nav-link active"
href="#">{opt.name}</IndexLink>
</li>);
}
render() {
return (
<div className="main-app-page">
<nav className="navbar navbar-default color-navbar fixed">
<div className="container-fluid">
{this.renderContent()}
</div>
</nav>
<div className="content">
{this.props.children}
</div>
</div>
);
}
}
export default App;
Routes.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Route, IndexRoute, browserHistory, Link } from 'react-router';
import App from './common/App';
import NotFound from './common/NotFound';
import Store from './store';
import Home from './components/Home';
import DatasetPage from './components/Images/DatasetPage';
import ImageWithRelateds from './components/Images/ImageWithRelateds';
import { options_NavBar } from './customize.js';
import { getQimList, resetQimList} from './actions/index';
const Test = ()=>{
return(<h2 style={{"paddingLeft":"35%"}} >W E L C O M E !</h2>)
};
export default (
<Route path="/" components={App} options={options_NavBar} history={browserHistory}>
<IndexRoute components={Test}/>
<Route path="/home" component={Home} />
<Route path="images" >
<Route path="oxford" component={DatasetPage} onEnter={()=>{
Store.dispatch(resetQimList());
Store.dispatch(getQimList('oxford'));
}} />
<Route path="paris" component={DatasetPage} onEnter={()=>{
Store.dispatch(resetQimList());
Store.dispatch(getQimList('paris'));
}} />
<Route path="instre" component={DatasetPage} onEnter={(e)=>{
Store.dispatch(resetQimList());
Store.dispatch(getQimList('instre'));
}} />
<Route path=":id" component={ImageWithRelateds} />
</Route>
<Route path="*" component={NotFound} />
</Route>
);
非常感谢你!
答案 0 :(得分:1)
父母给孩子们提供道具的反应中最基本的原则之一,孩子们向父亲发出事件(避免双向约束)
所以,你的App.js应该有isLoading变量的状态,而对于ImageWithRelateds组件你应该传递一个这样的事件(函数):
<Route path=":id" render={(props) => <ImageWithRelateds {...props} onFinishLoading={loadingFinished} />}>
和你的组件内部(应该是状态)应该具有这样的功能:
function loadingFinished() {
this.setState(prev => ({ ...prev, isLoading: false }))
}
然后,如果ImageWithRelateds组件内的加载完成,你会在你内部知道App.js,然后你就可以进行任何你想要的验证
我建议你阅读this article关于将事件(函数)传递给组件,为什么需要它以及如何有效地执行它
希望有所帮助!
修改强>
你的最终Routes.js代码看起来应该是这样的:
export default class Routes extends React.Component {
constructor() {
super();
this.state = { isLoading: false };
this.onLoadingFinishded = this.onLoadingFinishded.bind(this);
}
onLoadingFinishded() {
this.setState(state => {
...state,
isLoading: false
});
}
render() {
return <Route path="/" components={App} options={options_NavBar} history={browserHistory}>
<IndexRoute components={Test}/>
<Route path="/home" component={Home} />
<Route path="images" >
<Route path="oxford" component={DatasetPage} onEnter={()=>{
Store.dispatch(resetQimList());
Store.dispatch(getQimList('oxford'));
}} />
<Route path="paris" component={DatasetPage} onEnter={()=>{
Store.dispatch(resetQimList());
Store.dispatch(getQimList('paris'));
}} />
<Route path="instre" component={DatasetPage} onEnter={(e)=>{
Store.dispatch(resetQimList());
Store.dispatch(getQimList('instre'));
}} />
<Route path=":id" render={(props) => <ImageWithRelateds
{...props}
onLoadingFinished={this.onLoadingFinishded} />} />
</Route>
<Route path="*" component={NotFound} />
</Route>
}
}
(我不能确保代码完全正常运行,因为我没有你的所有项目,但最有可能的是)