如何在 React 中将异步属性从父组件传递到子组件
How to pass async props from parent-component to child-component in React
想象一下下面这个简单的 React 场景:
在这个例子中,我们有一个父组件和一个子组件。当父组件开始实例化时,它需要发出获取 childId 的请求。请求可以是也可以不是异步的。在我的特殊情况下,我使用的是电子。
之后父 ID 检索 childId 然后我想将该 childId 作为道具传递给子组件,然后发出另一个请求以检索它自己的状态。
这是我想要实现的功能。过去几个小时我一直在努力解决的问题围绕着 childId 的检索。不幸的是,React 在父组件检索 childId 之前创建了子组件。因此子组件无法检索它自己的状态。
我想看看是否有一种方法可以延迟子组件的渲染,直到父组件检索到 childId。
父组件
interface IState {
ticketId: number;
}
export class TicketOrchestrator extends React.Component<{}, IState> {
public state: IState = {
ticketId:0
};
public render(): React.ReactNode {
const onPrevious = () => console.log("FromPrevious");
const onNext = () => console.log("FromNext");
return (
<div>
<Ticket ticketId={this.state.ticketId} previous={onPrevious} next={onNext}/>
</div>
);
}
public componentDidMount(): void {
ipcRenderer.on("ticketOrchestrator", this.onMessage);
}
public componentWillUnmount(): void {
ipcRenderer.removeAllListeners("ticketOrchestrator");
}
private onMessage = (event: any, ticketId: any) => {
console.log("TicketId", ticketId);
this.setState({ ticketId: ticketId });
};
}
子组件
interface IState{
id: number,
header: {
ticketNumber: string,
title: string,
date: Date
},
body: {
content: string,
}
}
interface IProps{
ticketId: number,
previous: any,
next: any
}
export class Ticket extends React.Component<IProps, IState> {
public state:IState = {
id: this.props.ticketId,
header: {
ticketNumber: "",
title: "",
date: new Date()
},
body: {
content: "",
}
};
public render(): React.ReactNode {
const handleClickNext = () => this.props.previous();
const handleClickPrevious = () => this.props.next();
return (
<div>
<button onClick= {handleClickPrevious} >Previous</button>
<button onClick= {handleClickNext}>Next</button>
<div>
<h2>{this.state.header.title}</h2>
<h4>{this.state.header.date.toLocaleTimeString()}</h4>
</div>
<div>
<p>{this.state.body.content}</p>
<p>Id: {this.state.id}</p>
</div>
</div>
);
}
};
谢谢,
鲁本
假设您的 ticketId
在加载之前总是 0
,您可以只显示 alternative/loading 内容,而您的 ticketId
是 0
:
<div>
{this.state.ticketId === 0 ? (
<>Loading...</>
) : (
<Ticket
ticketId={this.state.ticketId}
previous={onPrevious}
next={onNext}
/>
)}
</div>;
想象一下下面这个简单的 React 场景:
在这个例子中,我们有一个父组件和一个子组件。当父组件开始实例化时,它需要发出获取 childId 的请求。请求可以是也可以不是异步的。在我的特殊情况下,我使用的是电子。
之后父 ID 检索 childId 然后我想将该 childId 作为道具传递给子组件,然后发出另一个请求以检索它自己的状态。
这是我想要实现的功能。过去几个小时我一直在努力解决的问题围绕着 childId 的检索。不幸的是,React 在父组件检索 childId 之前创建了子组件。因此子组件无法检索它自己的状态。
我想看看是否有一种方法可以延迟子组件的渲染,直到父组件检索到 childId。
父组件
interface IState {
ticketId: number;
}
export class TicketOrchestrator extends React.Component<{}, IState> {
public state: IState = {
ticketId:0
};
public render(): React.ReactNode {
const onPrevious = () => console.log("FromPrevious");
const onNext = () => console.log("FromNext");
return (
<div>
<Ticket ticketId={this.state.ticketId} previous={onPrevious} next={onNext}/>
</div>
);
}
public componentDidMount(): void {
ipcRenderer.on("ticketOrchestrator", this.onMessage);
}
public componentWillUnmount(): void {
ipcRenderer.removeAllListeners("ticketOrchestrator");
}
private onMessage = (event: any, ticketId: any) => {
console.log("TicketId", ticketId);
this.setState({ ticketId: ticketId });
};
}
子组件
interface IState{
id: number,
header: {
ticketNumber: string,
title: string,
date: Date
},
body: {
content: string,
}
}
interface IProps{
ticketId: number,
previous: any,
next: any
}
export class Ticket extends React.Component<IProps, IState> {
public state:IState = {
id: this.props.ticketId,
header: {
ticketNumber: "",
title: "",
date: new Date()
},
body: {
content: "",
}
};
public render(): React.ReactNode {
const handleClickNext = () => this.props.previous();
const handleClickPrevious = () => this.props.next();
return (
<div>
<button onClick= {handleClickPrevious} >Previous</button>
<button onClick= {handleClickNext}>Next</button>
<div>
<h2>{this.state.header.title}</h2>
<h4>{this.state.header.date.toLocaleTimeString()}</h4>
</div>
<div>
<p>{this.state.body.content}</p>
<p>Id: {this.state.id}</p>
</div>
</div>
);
}
};
谢谢, 鲁本
假设您的 ticketId
在加载之前总是 0
,您可以只显示 alternative/loading 内容,而您的 ticketId
是 0
:
<div>
{this.state.ticketId === 0 ? (
<>Loading...</>
) : (
<Ticket
ticketId={this.state.ticketId}
previous={onPrevious}
next={onNext}
/>
)}
</div>;