在 useEffect 中更新状态后重新加载反应组件
Reload react component after updating state inside useEffect
我有一个 React 组件,我正在更新 Mobx 中的状态,并希望在更新此状态时重新加载相同的组件。我有一个代理列表,我在一个组件中使用查询参数按类型获取代理,并基于我想从数据库中获取过滤数据的查询参数。
我的组件代码如下所示:
export interface IListAgenciesProps {
agencyType: string;
agencyTypeTitle: string;
}
const ListAgencies = (props: any) => {
let ctx = useContext(imsStore);
let agencies: IAgency[] = [];
useEffect(() => {
const agencyType = props.match.params["AgencyType"];
ctx.setAgency(agencyType);
async function agencyLoad(){
await ctx.loadAgencies();
agencies = ctx.agencies;
}
agencyLoad();
},
[agencies]);
let html: JSX.Element;
if (agencies.length > 0) {
html = ( <Container>
<Table celled selectable>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Agency Name</Table.HeaderCell>
<Table.HeaderCell>Telephone</Table.HeaderCell>
<Table.HeaderCell>Email</Table.HeaderCell>
<Table.HeaderCell>Is Active?</Table.HeaderCell>
<Table.HeaderCell>Hourly Rate</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{agencies.map(a => {
return (
<Table.Row>
<Table.Cell>{a.name}</Table.Cell>
<Table.Cell>{a.telephone}</Table.Cell>
<Table.Cell>{a.email}</Table.Cell>
<Table.Cell>{a.isActive}</Table.Cell>
<Table.Cell>{a.pricePerHour}</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
</Table>
</Container>
);
} else {
html = ( <Container>
<Header as='h1'>
Sorry, we couldn't find the agency type you're looking for.
</Header>
</Container>
);
}
return <>{html}</>;
};
export default observer(ListAgencies);
在我的 IMSStore.ts 中,它看起来像这样:
@observable agencies: IAgency[] = [];
@action loadAgencies = async () => {
this.agencies = [];
try {
const agencies = await agent.Agencies.list(this.agencyType);
agencies.forEach(agency => {
this.agencies.push(agency);
});
} catch (err) {
console.log(err);
} finally {
}
};
但是,在执行 return 语句时,我的第一个代码片段中的代理数组始终为空。因此,每次 useEffect 运行时,它都会调用 loadAgencies,并在 loadAgencies 中将代理的值重置为空数组。然后执行 return 语句。如何使 return 语句等待代理数组实际填满?
啊,好吧,如果你想让它保持相对相似,让我为你提出一个可能的简化建议:
export interface IListAgenciesProps {
agencyType: string;
agencyTypeTitle: string;
}
const ListAgencies = (props: any) => {
const agencyType = props.match.params["AgencyType"];
const ctx = useContext(imsStore);
const { agencies, loadAgencies } = ctx;
useEffect(() => {
loadAgencies(agencyType);
}, [agencyType]);
let html: JSX.Element;
if (agencies.length > 0) {
html = ( <Container>
<Table celled selectable>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Agency Name</Table.HeaderCell>
<Table.HeaderCell>Telephone</Table.HeaderCell>
<Table.HeaderCell>Email</Table.HeaderCell>
<Table.HeaderCell>Is Active?</Table.HeaderCell>
<Table.HeaderCell>Hourly Rate</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{agencies.map(a => {
return (
<Table.Row>
<Table.Cell>{a.name}</Table.Cell>
<Table.Cell>{a.telephone}</Table.Cell>
<Table.Cell>{a.email}</Table.Cell>
<Table.Cell>{a.isActive}</Table.Cell>
<Table.Cell>{a.pricePerHour}</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
</Table>
</Container>
);
} else {
html = ( <Container>
<Header as='h1'>
Sorry, we couldn't find the agency type you're looking for.
</Header>
</Container>
);
}
return <>{html}</>;
};
export default observer(ListAgencies);
商店:
@observable agencies: IAgency[] = [];
@action loadAgencies = async (agencyType) => {
try {
this.agencies = await agent.Agencies.list(agencyType);
} catch (err) {
console.log(err);
} finally {
}
};
所以现在发生的事情是我们正在简化组件,以便在安装时节省 agencyType
。然后在 deps 数组中为效果指定它意味着我们每次参数更改时调用 loadAgencies
。请注意,我们现在使用参数调用 ctx
方法。所以 loadAgencies
将采用该类型,去获取数据,然后将其设置为相同 @action
内的上下文变量。
然后,由于我们在组件内部从 ctx
中取消引用 agencies
,因此当 agencies
@observable
更新时它将重新呈现。我们不需要在效果异步中进行调用 - 只要数据返回,组件就会重新渲染。
我有一个 React 组件,我正在更新 Mobx 中的状态,并希望在更新此状态时重新加载相同的组件。我有一个代理列表,我在一个组件中使用查询参数按类型获取代理,并基于我想从数据库中获取过滤数据的查询参数。
我的组件代码如下所示:
export interface IListAgenciesProps {
agencyType: string;
agencyTypeTitle: string;
}
const ListAgencies = (props: any) => {
let ctx = useContext(imsStore);
let agencies: IAgency[] = [];
useEffect(() => {
const agencyType = props.match.params["AgencyType"];
ctx.setAgency(agencyType);
async function agencyLoad(){
await ctx.loadAgencies();
agencies = ctx.agencies;
}
agencyLoad();
},
[agencies]);
let html: JSX.Element;
if (agencies.length > 0) {
html = ( <Container>
<Table celled selectable>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Agency Name</Table.HeaderCell>
<Table.HeaderCell>Telephone</Table.HeaderCell>
<Table.HeaderCell>Email</Table.HeaderCell>
<Table.HeaderCell>Is Active?</Table.HeaderCell>
<Table.HeaderCell>Hourly Rate</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{agencies.map(a => {
return (
<Table.Row>
<Table.Cell>{a.name}</Table.Cell>
<Table.Cell>{a.telephone}</Table.Cell>
<Table.Cell>{a.email}</Table.Cell>
<Table.Cell>{a.isActive}</Table.Cell>
<Table.Cell>{a.pricePerHour}</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
</Table>
</Container>
);
} else {
html = ( <Container>
<Header as='h1'>
Sorry, we couldn't find the agency type you're looking for.
</Header>
</Container>
);
}
return <>{html}</>;
};
export default observer(ListAgencies);
在我的 IMSStore.ts 中,它看起来像这样:
@observable agencies: IAgency[] = [];
@action loadAgencies = async () => {
this.agencies = [];
try {
const agencies = await agent.Agencies.list(this.agencyType);
agencies.forEach(agency => {
this.agencies.push(agency);
});
} catch (err) {
console.log(err);
} finally {
}
};
但是,在执行 return 语句时,我的第一个代码片段中的代理数组始终为空。因此,每次 useEffect 运行时,它都会调用 loadAgencies,并在 loadAgencies 中将代理的值重置为空数组。然后执行 return 语句。如何使 return 语句等待代理数组实际填满?
啊,好吧,如果你想让它保持相对相似,让我为你提出一个可能的简化建议:
export interface IListAgenciesProps {
agencyType: string;
agencyTypeTitle: string;
}
const ListAgencies = (props: any) => {
const agencyType = props.match.params["AgencyType"];
const ctx = useContext(imsStore);
const { agencies, loadAgencies } = ctx;
useEffect(() => {
loadAgencies(agencyType);
}, [agencyType]);
let html: JSX.Element;
if (agencies.length > 0) {
html = ( <Container>
<Table celled selectable>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Agency Name</Table.HeaderCell>
<Table.HeaderCell>Telephone</Table.HeaderCell>
<Table.HeaderCell>Email</Table.HeaderCell>
<Table.HeaderCell>Is Active?</Table.HeaderCell>
<Table.HeaderCell>Hourly Rate</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{agencies.map(a => {
return (
<Table.Row>
<Table.Cell>{a.name}</Table.Cell>
<Table.Cell>{a.telephone}</Table.Cell>
<Table.Cell>{a.email}</Table.Cell>
<Table.Cell>{a.isActive}</Table.Cell>
<Table.Cell>{a.pricePerHour}</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
</Table>
</Container>
);
} else {
html = ( <Container>
<Header as='h1'>
Sorry, we couldn't find the agency type you're looking for.
</Header>
</Container>
);
}
return <>{html}</>;
};
export default observer(ListAgencies);
商店:
@observable agencies: IAgency[] = [];
@action loadAgencies = async (agencyType) => {
try {
this.agencies = await agent.Agencies.list(agencyType);
} catch (err) {
console.log(err);
} finally {
}
};
所以现在发生的事情是我们正在简化组件,以便在安装时节省 agencyType
。然后在 deps 数组中为效果指定它意味着我们每次参数更改时调用 loadAgencies
。请注意,我们现在使用参数调用 ctx
方法。所以 loadAgencies
将采用该类型,去获取数据,然后将其设置为相同 @action
内的上下文变量。
然后,由于我们在组件内部从 ctx
中取消引用 agencies
,因此当 agencies
@observable
更新时它将重新呈现。我们不需要在效果异步中进行调用 - 只要数据返回,组件就会重新渲染。