2

There is some related threads, and a lot of opinions on this subject so I will try to summarize my findings. Notice I am a beginner so this is my best bet, and the data I gathered from related posts and this.

In general most people agree that if the parent call's a child it is bad practice. In the related post for this article there is an accepted answer, where the person answers that it is a bad practice but possible. @mat sz answer directed me on the right path. I have updated my sample for others to see. I pass a parameter to my child component. In the child component I add a listener for changes on that parameter:

useEffect(() => {
  if (props.toggleClose != null) {
    setToggleJobTable(false);
  }
}, [props.toggleClose]);

I just toggle that parameter between true/false in my parent. Not beautiful but my best bet on how to do this in react.


Original question

I found a lot of samples in here on how to pass variables to child components, how to raise events from child components to parent components, and even how to pass a function to a child component from parent component. But what about last scenario. How to call a function in a child component from the parent. In this sample I would like to trigger the closeAll function in the child component from the parent:

https://codesandbox.io/s/toggle-all-qxkgy?fontsize=14&hidenavigation=1&theme=dark

I still dont have an answer on this, but a lot of good input in the posts. For me it sounds like the right approach here would be parsing a parameter to the child as parameter. My question is then, if I pass a parameter to the child component. How do I toogle when the parent changes that value, then my closeAll function in the child is called?

It is also stated that it could be wrong design. If you look on my very simple sample how should it else be designed? All input are welcome. I have very little experience with REACT so I am trying to understand how an experienced REACT developer would solve this simple task/sample.

Thomas Segato
  • 4,567
  • 11
  • 55
  • 104
  • Why would you need such a thing? It's an React anti pattern. Usually the parents are the smart component s and children are dumb that get state and callbacks. However if that's your only option you can do it by paasing a ref to the child and your child must be a class component, then you get access to the class methods.see here https://stackoverflow.com/questions/37949981/call-child-method-from-parent – gadi tzkhori Feb 01 '20 at 10:01
  • I want to make a control with collabsible cards. And the consumer of that component must be apple to callapse all. Is that such a wierd requirement? Like if you had a treeview where each node was a child component and you had an collapse all. Can't see that is a wierd requirement. – Thomas Segato Feb 01 '20 at 10:50
  • But thanks, I was the ref part on REACT's home page, but I would prefer arrow functions as rest of our components is like that. – Thomas Segato Feb 01 '20 at 10:51
  • You can use `Provider` and `useContext`. And then any nested child can get the provider api and collapse all.but in general the parent should hold most of the api and pass it to children. – gadi tzkhori Feb 01 '20 at 11:29
  • OK I will try google provider and see if I can get that to work. – Thomas Segato Feb 01 '20 at 11:30
  • I havent been able to find anything on this. So question is open for everyone. Best would to be modify provided sample. – Thomas Segato Feb 01 '20 at 14:33

1 Answers1

1

It's not possible, parent components are not able to access the functions inside of child components.

You could use something like Redux or MobX to create a global state and then rely on global state for that, or you, ideally, should restructure your code in a way that does not require this, for example if your function (the one that has to be called inside of parent) changes state of a child component - move that state to the parent component, and then provide that state via props to the child component (along with a setter function, if required).

Mat Sz
  • 2,524
  • 1
  • 10
  • 23
  • I was thinking about passing a state variable. But you would have to toggle it which would be kind of wierd. Lets say – Thomas Segato Feb 01 '20 at 09:47
  • That's why I would suggest thinking of a way that would avoid doing that altogether, or maybe using Redux/MobX. Also, that's not really weird, it's just the React way. – Mat Sz Feb 01 '20 at 09:49
  • OK, I think it is more simple than introducing another framework. I keep the post open for a day or two if others have inputs. Thanks alot. – Thomas Segato Feb 01 '20 at 09:51
  • I have updated my sample. Can you show how you would pass the toggle variable to the child and react on it? – Thomas Segato Feb 01 '20 at 09:56
  • You can just pass the setCloseAll function as a prop and then use it inside of the child component. – Mat Sz Feb 01 '20 at 09:57
  • you don't need Redux or MobX just define the function in the parent and pass it to the child component. – Junius L Feb 01 '20 at 09:57
  • That's what I'm saying is ideal, but Redux/MobX also solve the problem. – Mat Sz Feb 01 '20 at 09:57
  • and why does ```closeAll``` not inside ```CollapseBox```? – Junius L Feb 01 '20 at 09:59
  • @Mat Sz It is possible, look in my comment – gadi tzkhori Feb 01 '20 at 10:15
  • But arent you swapping the goal here? I dont want to call a function in the parent, I want to get the closeAll function in the child to be called? Feel free to update sample with your thoughts. – Thomas Segato Feb 01 '20 at 10:43