Accepted answer

Ah, ok if you wanna keep it relatively similar, let me suggest a possible simplification for ya:

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(() => {
  }, [agencyType]);

  let html: JSX.Element;
  if (agencies.length > 0) {
    html = ( <Container>
        <Table celled selectable>
              <Table.HeaderCell>Agency Name</Table.HeaderCell>
              <Table.HeaderCell>Is Active?</Table.HeaderCell>
              <Table.HeaderCell>Hourly Rate</Table.HeaderCell>
            { => {
              return (
  } else {
    html = ( <Container>
        <Header as='h1'>
          Sorry, we couldn't find the agency type you're looking for.

  return <>{html}</>;

export default observer(ListAgencies);


@observable agencies: IAgency[] = [];
@action loadAgencies = async (agencyType) => {
    try {
      this.agencies = await agent.Agencies.list(agencyType);
    } catch (err) {
    } finally {

So what's happening now is we're simplifying the component so it saves the agencyType on mount. Then specifying it in the deps array for the effect means that we call loadAgencies everytime the params change. Notice we're now calling the ctx method with a parameter. So loadAgencies is gonna take in that type, go fetch the data, and then set it to the context variable all inside the same @action.

Then, since we've dereferenced agencies from ctx inside the component, it will re-render when the agencies @observable is updated. We don't need to make the call inside the effect async - the component will re-render whenever the data comes back.

Related Query

More Query from same tag