Add prefab to panel in script

I have a canvas, in canvas I have a panel, in the script i want to add element to the panel. That’s the code, which doesn’t work for me

   public GameObject b;
   public Canvas canvas;

    void CreateA() {
          RectTransform panel = canvas.GetComponentInChildren<RectTransform>(); 
          GameObject a = (GameObject)Instantiate(b); 
          a.transform.SetParent(panel.transform, false);
    }

In the end it adds element to the canvas, not the panel.

How can to add it to the panel?

Why not just have:

public GameObject b;
public Transform panel;
 
void CreateA() {
       GameObject a = (GameObject)Instantiate(b); 
       a.transform.SetParent(panel.transform, false);
}

RectTransform panel = canvas.GetComponentInChildren();

will get the RectTransform of ANY child, not necessarily the panel you want. if you know the name of the panel then search for it by name

var panel = GameObject.Find("PanelNameHere");
if (panel != null)  // make sure you actually found it!
{
    GameObject a = (GameObject)Instantiate(b); 
    a.transform.SetParent(panel.transform, false);
}

Actually I believe what is happening is GetComponentInChildren does not function exactly how you would think. It starts with itself and looks for RectTransforms there, so you are in fact finding the RectTransform of the canvas not the RectTransform of the Panel.

I know this seems backwards and have wondered why unity does this, but the object looking for components in child seems to include itself in that search, go figure.

If you did GetComponentsInChildren and took the second element in the array [1], this should be your Panels rectTransform