Javascript 在获取所有信息之前,如何阻止要渲染的React组件?
在渲染我的组件之前,我需要获取一些信息。这些信息将由API提供,并通过ajax调用获取 我正试图在渲染组件之前等待10秒,但它显示:Javascript 在获取所有信息之前,如何阻止要渲染的React组件?,javascript,reactjs,Javascript,Reactjs,在渲染我的组件之前,我需要获取一些信息。这些信息将由API提供,并通过ajax调用获取 我正试图在渲染组件之前等待10秒,但它显示: 未捕获不变冲突:Login.render():必须返回有效的组件。您可能返回了未定义、数组或其他无效对象。 我可以在履行承诺后提交我的组件吗 /** Page Login */ class Login extends React.Component { /** * @constructor * @param {object} props La f
未捕获不变冲突:Login.render():必须返回有效的组件。您可能返回了未定义、数组或其他无效对象。
我可以在履行承诺后提交我的组件吗
/** Page Login */
class Login extends React.Component {
/**
* @constructor
* @param {object} props La fonction super() appelle le parent pour y transmettre ses propriétés
*/
constructor(props) {
super(props);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
/**
* Reçoit les valeurs des formulaires
*/
handleFormSubmit(data) {
const { dispatch } = this.props;
dispatch(fetchLoginAuth(data));
}
normalRender() {
return (
<div id="login-page">
<div className="container-fluid">
<div className="row">
<div className="col-md-2">
<Link to="/" className="home-link"><img src={BASE_URL + '/assets/img/logo.svg'} alt="Logo" /></Link>
</div>
</div>
<div className="row">
<div className="col-lg-4 col-lg-offset-4">
<h1><FormattedMessage {...messages.loginPageTitle} /></h1>
</div>
</div>
{React.cloneElement(this.props.children || <div />, { onSubmit: this.handleFormSubmit, login: this.props.login })}
</div>
</div>
);
}
/**
* Render le component - ReactTransitionGroup
* @return {JSX} Rend la page Registration
*/
render() {
setTimeout(this.normalRender, 10000);
}
}
/**页面登录*/
类登录扩展了React.Component{
/**
*@constructor
*@param{object}props La fonction super()将父对象转换为属性
*/
建造师(道具){
超级(道具);
this.handleFormSubmit=this.handleFormSubmit.bind(this);
}
/**
*关于公式的价值
*/
handleFormSubmit(数据){
const{dispatch}=this.props;
调度(获取登录号(数据));
}
normalRender(){
返回(
{React.cloneElement(this.props.children | | |,{onSubmit:this.handleFormSubmit,login:this.props.login}
);
}
/**
*渲染le组件-ReactTransitionGroup
*@return{JSX}Rend la页面注册
*/
render(){
setTimeout(this.normalRender,10000);
}
}
我将ES6与JSX、redux一起使用,这是一个带有react路由器的通用路由器
非常感谢你的帮助 您可以尝试以下方法
/** Page Login */
class Login extends React.Component {
constructor(props) {
...
this.state = {
ready: false
};
}
componentWillMount() {
setTimeout(this.handleLoading, 10000);
}
handleLoading() {
this.setState({ ready: true });
}
render() {
if(!this.state.ready)
return null;
return normalRender();
}
}
暂停渲染似乎有问题 为什么不使用占位符子组件渲染组件的一部分呢。。 然后,当ajax调用完成时,触发一个操作来更改状态并呈现原始组件
在用户体验和优雅度方面都会更好。始终让React渲染 在执行异步操作时,请显示加载微调器或其他内容
render() {
<div>
{ this.state.isLoading &&
<div>Loading.. please wait!</div>
}
{ !this.state.isLoading &&
<div>My data has arrived!</div>
}
</div>
}
render(){
{this.state.isLoading&&
正在加载..请稍候!
}
{!正在加载此.state.isLoading&&
我的数据已经到了!
}
}
以下是我通常做的事情:
class Login extends React.Component {
constructor(props) {
//IMPLEMENT OTHER JUNK HERE
this.state = {
data: null //This is what our data will eventually be loaded into
};
}
componentDidMount() {
this.loadData();
}
loadData() {
/*LOAD DATA, INSERT BELOW LINE IN CALLBACK FUNCTION
this.setState({
data: //LOADED DATA
});
*/
}
render() {
if (!this.state.data) {
return <div />
}
//WE HAVE DATA, DO A NORMAL RENDER
return (
<div id="login-page">
<div className="container-fluid">
<div className="row">
<div className="col-md-2">
<Link to="/" className="home-link"><img src={BASE_URL + '/assets/img/logo.svg'} alt="Logo" /></Link>
</div>
</div>
<div className="row">
<div className="col-lg-4 col-lg-offset-4">
<h1><FormattedMessage {...messages.loginPageTitle} /></h1>
</div>
</div>
{React.cloneElement(this.props.children || <div />, { onSubmit: this.handleFormSubmit, login: this.props.login })}
</div>
</div>
);
}
}
类登录扩展了React.Component{
建造师(道具){
//在这里实现其他垃圾
此.state={
data:null//这是我们的数据最终将加载到的内容
};
}
componentDidMount(){
这是loadData();
}
loadData(){
/*加载数据,在回调函数的下行插入
这是我的国家({
数据://加载的数据
});
*/
}
render(){
如果(!this.state.data){
返回
}
//我们有数据,做一个普通的渲染
返回(
{React.cloneElement(this.props.children | | |,{onSubmit:this.handleFormSubmit,login:this.props.login}
);
}
}
下面是将要发生的事情的细目
this.state.data
为null
,我们将其传递到if块,并返回
this.setState()
调用,这将强制重新渲染this.state.data
现在包含一个值,因此我们跳过if块并呈现普通内容编辑(2019年10月11日):迁移使用构造函数替代已接受的答案。我个人觉得这有点干净
class Menu extends Component {
state = {}
constructor(props) {
super(props)
loadData().then(data =>
this.setState({data: data})
)
}
async loadData() {
//get your data
}
render() {
if (isEmpty(this.state)) {
return <div>Loading</div>
}
return (
<div id="site">
{data}
</div>
)
}
类菜单扩展组件{
状态={}
建造师(道具){
超级(道具)
loadData()。然后(数据=>
this.setState({data:data})
)
}
异步加载数据(){
//获取您的数据
}
render(){
如果(isEmpty(本州)){
回装
}
返回(
{data}
)
}
如果您必须在多个位置处理相同的情况,或者您不必仅仅因为要跟踪表示组件中的异步函数回调而使用state,那么有一种简单的方法可以解决这些问题,请参阅
react promise提供一个名为usePromise
的钩子(您可以玩)
从“React”导入React;
从“反应承诺”中导入usePromise;
导入“/styles.css”;
const prom=新承诺((resolutionFunc,rejectionFunc)=>{
//在成功响应后调用异步返回值
setTimeout(函数(){
resolutionFunc(Hello World);
}, 5000);
});
常量应用=()=>{
const{value,load}=usePromise(prom);
如果(装载)返回装载;
返回{value};
};
导出默认应用程序;
延迟一段时间后,您可以看到Hello world从不阻止渲染。返回null可能会引发错误。渲染空div总是更好。这是错误的:检查:您也可以返回null或false以表示不希望渲染任何内容。在幕后,React渲染标记以使用当前的扩散算法。When返回null或false,ReactDOM.findDOMNode(this)将返回null。Franco Risso:有道理。从我读到的内容来看,最好返回一个空div,但我忘记了它背后的逻辑。@molson504x空div的问题是,您无法知道div是否有默认显示在屏幕上的样式,您可以确定不会显示任何内容.我想要更少的用户界面
import React from "react";
import usePromise from "react-promise";
import "./styles.css";
const prom = new Promise((resolutionFunc, rejectionFunc) => {
// call your async return values after succesfull response
setTimeout(function () {
resolutionFunc(<h1> Hello World </h1>);
}, 5000);
});
const App = () => {
const { value, loading } = usePromise(prom);
if (loading) return <div> loading </div>;
return <div>{value}</div>;
};
export default App;