Reactjs 组件在呈现之前不会等待API响应
我尝试过在API调用后设置标志并使用componentDidMount进行条件呈现,但无法让该组件在呈现之前等待API响应。我知道API响应是有效的,因为它在控制台中记录为ok。我是新手,你能告诉我我做错了什么吗?我已经研究了Stackoverflow上的类似问题,但找不到解决方法。非常感谢 我已经从代码片段中删除了一些方法,以使其更具可读性Reactjs 组件在呈现之前不会等待API响应,reactjs,Reactjs,我尝试过在API调用后设置标志并使用componentDidMount进行条件呈现,但无法让该组件在呈现之前等待API响应。我知道API响应是有效的,因为它在控制台中记录为ok。我是新手,你能告诉我我做错了什么吗?我已经研究了Stackoverflow上的类似问题,但找不到解决方法。非常感谢 我已经从代码片段中删除了一些方法,以使其更具可读性 import { OTSession, OTPublisher, OTStreams, OTSubscriber } from 'opentok-reac
import { OTSession, OTPublisher, OTStreams, OTSubscriber } from 'opentok-react';
import {
SAMPLE_SERVER_BASE_URL,
} from './config';
export default class CallPane extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
connection: 'Connecting',
publishVideo: true,
apiKey: '',
sessionId: '',
token: '',
isLoaded: false,
};
componentDidMount() {
fetch(SAMPLE_SERVER_BASE_URL + '/session')
.then(data => data.json())
.then(data => {
console.log(data)
this.setState({ apiKey: data.apiKey })
console.log(data.apiKey)
this.setState({ sessionId: data.sessionId })
console.log(data.sessionId)
this.setState({ token: data.token })
console.log(data.token)
this.setState({ isLoaded: true })
})
.catch((err) => {
console.error('Failed to get session credentials', err);
alert('Failed to get opentok sessionId and token. Make sure you have updated the config.js file.');
});
}
render() {
const { error, connection, publishVideo } = this.state;
// const { apiKey, sessionId, token } = this.state;
return (
// (isLoaded)
<div>
<div id="sessionStatus">Session Status: {connection}</div>
{error ? (
<div className="error">
<strong>Error:</strong> {error}
</div>
) : null}
<OTSession
apiKey={this.apiKey}
sessionId={this.sessionId}
token={this.token}
onError={this.onSessionError}
eventHandlers={this.sessionEventHandlers}
>
<button id="videoButton" onClick={this.toggleVideo}>
{publishVideo ? 'Disable' : 'Enable'} Video
</button>
<OTPublisher
properties={{ publishVideo, width: 250, height: 250, }}
onPublish={this.onPublish}
onError={this.onPublishError}
eventHandlers={this.publisherEventHandlers}
/>
<OTStreams>
<OTSubscriber
properties={{ width: 300, height: 300 }}
onSubscribe={this.onSubscribe}
onError={this.onSubscribeError}
eventHandlers={this.subscriberEventHandlers}
/>
</OTStreams>
</OTSession>
</div>
);
}
}
从“opentok react”导入{OTSession、OTPublisher、OTStreams、OTSubscriber};
进口{
示例\u服务器\u基础\u URL,
}从“./config”开始;
导出默认类CallPane扩展React.Component{
建造师(道具){
超级(道具);
此.state={
错误:null,
连接:'正在连接',
publishVideo:没错,
apiKey:“”,
会话ID:“”,
令牌:“”,
isLoaded:false,
};
componentDidMount(){
获取(示例\u服务器\u基础\u URL+'/session')
.then(data=>data.json())
。然后(数据=>{
console.log(数据)
this.setState({apiKey:data.apiKey})
console.log(data.apiKey)
this.setState({sessionId:data.sessionId})
console.log(data.sessionId)
this.setState({token:data.token})
console.log(data.token)
this.setState({isLoaded:true})
})
.catch((错误)=>{
console.error('获取会话凭据失败',err);
警报('未能获取opentok会话ID和令牌。请确保已更新config.js文件');
});
}
render(){
const{error,connection,publishVideo}=this.state;
//const{apiKey,sessionId,token}=this.state;
返回(
//(已加载)
会话状态:{connection}
{错误(
错误:{Error}
):null}
{publishVideo?'Disable':'Enable'}视频
);
}
}
您可以将if语句放入渲染方法中:
render() {
const { error, connection, publishVideo, isLoaded } = this.state;
// const { apiKey, sessionId, token } = this.state;
if(!isLoaded) {
// not loaded
return (
<div>Loading...</div>
)
}
return (
// (isLoaded)
// your code
);
}
render(){
const{error,connection,publishVideo,isLoaded}=this.state;
//const{apiKey,sessionId,token}=this.state;
如果(!已加载){
//未加载
返回(
加载。。。
)
}
返回(
//(已加载)
//你的代码
);
}
您可以使用一个简单的if语句,检查资源是否已准备就绪。如果未准备就绪,则呈现加载条或类似内容。从:
您还可以使用类似于以下的方法,以确保始终渲染另一个组件
class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
externalData: null,
};
}
componentDidMount() {
fetch(SAMPLE_SERVER_BASE_URL + '/session')
.then(data => data.json())
.then(data => {
this.setState({ externalData: data });
});
}
//This render is begin called even before props getting updated
render() {
return (
<div>
<h1>{'This will always render yay '}</h1>
{ this.state && this.state.externalData &&
<div>{'This will just render after the return of the async call'}</div>
}
</div>
)
}
}
class ExampleComponent扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
外部数据:null,
};
}
componentDidMount(){
获取(示例\u服务器\u基础\u URL+'/session')
.then(data=>data.json())
。然后(数据=>{
this.setState({externalData:data});
});
}
//即使在道具更新之前,也会开始调用此渲染
render(){
返回(
{'这将始终呈现yay'}
{this.state&&this.state.externalData&&
{'这将在异步调用返回后立即呈现'}
}
)
}
}
欢迎使用SO!首先,请注意,通过在传递给setState的对象中包含多个属性,您可以一次设置多个状态变量。但更重要的是,您在何处使用isLoaded?您设置了isLoaded,但注释了我认为您要使用它的行。假设这只是为了测试,请签出,但特别是首先,检查您的错误
条件与您的已加载
条件之间的差异。很棒-设置状态对象的优点。感谢@HammerN'Songs。现在阅读文档。感谢@Tom Scholz,组件现在正在正确渲染!由于某种原因,来自的道具没有传递到OTSession component和我得到“ReferenceError:OT未定义”。这可能与状态有关,因为API响应有效,并且可以将其正确记录在与呈现函数相同的范围内。我似乎无法在此注释中添加多行代码。您可以创建一个JSFIDLE或codesandbox来重现问题吗?现在排序好了,谢谢欧-是我的错,只是我试图访问属性的方式!
class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
externalData: null,
};
}
componentDidMount() {
fetch(SAMPLE_SERVER_BASE_URL + '/session')
.then(data => data.json())
.then(data => {
this.setState({ externalData: data });
});
}
//This render is begin called even before props getting updated
render() {
return (
<div>
<h1>{'This will always render yay '}</h1>
{ this.state && this.state.externalData &&
<div>{'This will just render after the return of the async call'}</div>
}
</div>
)
}
}