A single bi-directional data flow link is not necessarily that bad. It has some ambiguity over which side “wins” under some conditions, and it tends to be sensitive to timing in a way that one-way flow would not be.
But that’s not really the big problem. The big problem is that as you keep adding more links, it’s easy to create loops without realizing it. Once you have a loop, reasoning about the system gets extremely hard. This manifests itself as bizarre bugs, often popping up in places that seem totally unrelated to the changes you just made.
To avoid that complexity, we want the data flow to be a tree, not a graph. To keep it as a tree, you need some rule that will prevent the creation of loops. “Data down” is that rule. As long as data only flows from parents to children, you can’t accidentally make a loop.
“Actions up” is the flip side, because children obviously do need to influence their parents. But they can do so explicitly by asking the parent to change some state rather than implicitly by just reaching out and changing it.