Home > Software design >  Issue in ReactJs function calling between components
Issue in ReactJs function calling between components

Time:03-30

Problem:- I have written a function named "getData()" in "App.js" and i am able to call it in "User.js". Code is written below.

But, What if i have written that "getdata()" function in "User.js" and i have to call it in "App.js". How can i do that? i am not able to do so.. please guide me.

App.js

import User from './User'
function App() {
  function getData() {
    alert("Hello from app component")
  }
  return (
    <div className="App">
     <User data={getData}/>
    </div>
  );
}
export default App: 

User.js

function User(props) {
        return(
            <div>
                <h1>User Component</h1>
                <button onClick={props.data}> Call Function</button>
            </div>
    export default User;

CodePudding user response:

What if i have written that "getdata()" function in "User.js" and i have to call it in "App.js". How can i do that?

It's not what file it's in that's the issue. Your current getData function is inside the App component, so it has access to the App component's state and other instance information. It's okay for App to pass that to User because it lets User tell App when something has changed. This is common when you lift state up. But it only makes sense if getData needs access to App's internal information.

The converse (a function in User that App uses) probably doesn't make sense in the React world. App shouldn't rely on User that way; User is App's child, not the other way around. And unsurprisingly, doing it (while possible) is awkward and error-prone.

Assuming it doesn't have to be created inside a component function, you could put getData in User.js (outside the User component) and export it, then import it and use it in App. That might make sense if the function is closely related to User and you really only expect App to need it when it's using User. (For example: A constructor that creates instances of a data structure that User expects in its props.) But it also creates a circular dependency between App.js and User.js, which is often just fine but sometimes problematic.

Alternatively, you might put it a completely different file, say getData.js, and put it there:

export function getData() {
    // ...
}

Then import it into App.js and/or User.js as needed.

CodePudding user response:

App.js

import React, { useRef } from 'react';
import User from './User';

function App() {
  const childRef = useRef();

  return (
    <div className="App">
      <User ref={childRef} />
      <button onClick={() => childRef.current.getData()}>Call Function</button>
    </div>
  );
}
export default App;

User.js

import React, { forwardRef, useImperativeHandle } from 'react';

const User = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    getData() {
      alert('Hello from user component');
    },
  }));

  return (
    <div>
      <h1>User Component</h1>
    </div>
  );
});
export default User;
  • Related