It depends greatly on the structure and usage pattern of those data structures.
The primary consideration is that it is useful to avoid Rc around some part that is to be mutated (rather than replaced entirely), since then one has to deal with the constraints of shared mutability (such as an Rc<RefCell<Foo>>. In that case, one might instead arrange so that the maps instead hold some index or key value identifying the Foo, rather than storing Rc<Foo> in the maps directly. That way, each Foo remains singly owned (from the perspective of ownership and borrow checking) and can be mutated through ordinary &mut access.
One might also avoid Rc in the same way with the intent of reducing the total number of allocations; how much this matters depends on the number of Foos and how many allocations are involved in each one anyway. But you should never try to tweak your program to be faster without first having noticed that it is slow, and second, measured how it is slow (profiling and benchmarking).
No, you can't use references that point to other parts of the structure that owns the references. This is both because the language contains no way to express the lifetime of those references, and if it could, it would still be difficult to express that an entry and its reference may be removed together, but an entry must not be removed without first removing its references.
This is called the "self-referential struct" problem.
Oops, I did not notice there is no struct involved here. With local variables only, this can work, as long as you do not ever need to remove items from the vector. Whether this is adequate or impossible depends entirely on the application.
That case isn't even self-referential; after the function returns, there is no owner of foos at all. When you want a data structure with that arrangement of pointers, the pointers must be Rc (or Arc) and not &.
Yeah, you'll need to make sure that foos outlive Context: you can't put it into the Context, as it would create self-references, but if foos lives somewhere else and passed in as a parameter it should work.
It all depends on what lifetimes you have for the derived maps, and when/if the vector gets updated.