Reputation: 374
I am totally blank on how to use a function that is inside a component and needs to be used in another component.
Here is a simple program:
Test.js
export default function Test(){
const testFunc = () => {
console.log("it is working")
}
return(
<div>
Hi
</div>
)
}
Test2.js
export default function Test2(){
return(
<button onClick={}> // Here I want to use testFunc() from Test file
Click
</button>
)
}
Could someone please explain how can it be achieved to access the function in Test2 file. Thanks in advance!!
Upvotes: 1
Views: 5554
Reputation: 1
Well you can use combination of useEffect and global state management.
Define that function inside useEffect and define one global state using any state management library and pass this state as dependency. now rather than calling that function from anyware just update this dependency state from anywere and useEffect will take care of calling that function.
I have recently used this for showing popup when user is filling some form and they have modified state and they try to navigate to somewhere else in the application.
Upvotes: 0
Reputation: 24661
Usually, context is used to share the same state between many components that aren't in parent-children relations. codesandbox
First, create a context:
const MyContext = createContext();
And context provider:
const MyContextProvider = ({ children }) => {
const [myState, setMyState] = useState(0);
return (
<MyContext.Provider value={{ myState, setMyState }}>
{children}
</MyContext.Provider>
);
};
And context hook (for convenience):
const useMyContext = () => useContext(MyContext);
Remember to use the provider in the common ancestor of the components:
function App() {
return (
<MyContextProvider>
<Component1 />
<Component2 />
</MyContextProvider>
);
}
Create your components:
function Component1() {
// as you can see, you can access the function here
const { setMyState } = useMyContext();
return (
<button onClick={() => setMyState((state) => state + 1)}>click me</button>
);
}
function Component2() {
// and the value here
const { myState } = useMyContext();
return myState;
}
Upvotes: 1
Reputation: 517
As Konrad said in the comments, this can't be possible since these 2 components lack no relationship (Neither Components are rendering or calling each other within)
Something you could do is Render the Test2.js
component within Test.js
and add a callback like so:
Test.js
import Test2 from '...';
export default function Test(){
const testFunc = () => {
console.log("it is working")
}
return(
<div>
Hi
<Test2 callbackProp={testFunc} />
</div>
)
}
Test2.js
export default function Test2({callbackProp}){
return(
<button onClick={() => {callbackProp();} }> // Here I want to use testFunc() from Test file
Click
</button>
)
}
Now whenever Test.js is rendered, it will also render Test2 (Since Test is rendering a Test2 Component) but whenever you click the button within Test2, it will execute the callback which is a function passed from Test
Nonetheless though, it's impossible to call any functions from another Component without passing down a prop like this (for future reference)
Upvotes: 3
Reputation: 2019
Welcome to the React community.
To use a function that is inside a component and needs to be used in another component.
You need a common parent, that handles the function.
Let's say you have the following structure.
export const ParentComponent = () => {
return <>
<Test1 />
<Test2 />
<>
}
If you want some function in Test1 to affect Test2, then you do what in react is called lifting state up https://reactjs.org/docs/lifting-state-up.html
ParentComponent
export const ParentComponent = () => {
const [value, setValue] = useState('')
return <>
<Test1 setValue={setValue} />
<Test2 value={value} />
<>
}
Test1
export const Test1 = (props) => {
return <>
<input onChange={(e) => props.setValue(e.target.vale} />
<>
}
Test2
export const Test2 = (props) => {
return <p>{props.value}</p>
}
When a component renders another component, it is called the parent of the rendered child. Imagine React as a tree data structure where the App.tsx/jsx
will be the tree's root.
Inspecting the code above, we can see that we have a function held in the parent. This is the function you would probably consider putting in Test1
. However, if you need to use it in another component, that is not a child of the current element. You will need to find the nearest common parent and pass the functionality down like in the example above.
I hope it makes sense. If not, I recommend glancing at the Main Concepts part of the official React documentation. https://reactjs.org/docs/getting-started.html
Upvotes: 2
Reputation: 175
You can either pass it down from a parent component, shown below, or you can use a custom hook
Parent Component:
import Child from './Child.js'
export default function Parent() {
const functionToBePassed = () => { ... }
return (
<Child func={functionToBePassed}>
)
}
Or you can do it via a custom hook
Two files, first one is the hook
export default function useFunc() {
const functionToBeShared = () => {...}
return { functionToBeShared }
}
//this is any component that wants to use the hook
import useFunc from ./useFunc;
export default function ComponentThatUsesHook() {
const {functionToBeShared} = useFunc();
}
Upvotes: 2
Reputation: 870
You will want to pass the function as a prop to the child component. You can't or I should say shouldn't pass a prop to a parent, you can do this but is not a react way and never recommended. What you would do in this case is but the logic in the parent because both siblings are needing access to it.
const App = () => {
const clickHandler = () => {
alert("Click event")
}
return (
<div className="App">
<ChildOne clickHandler={clickHandler}/>
<ChildTwo clickHandler={clickHandler}/>
</div>
)
}
}
Upvotes: 2