Using React [15.6.1] Redux [3.7.2] and Router [4.1.1] I'm tryin to access a method that belongs to other (siblings) components but can't seem to be able to access them. Is there anyway to export those methods?
----------
¦ Parent ¦
----------
¦
-------------------------------
¦ ¦ ¦
----------- ----------- -----------
¦ Child 1 ¦ ¦ Child 2 ¦ ¦ Child 3 ¦
----------- ----------- -----------
// Child 1 has a method submitChild1()
// Child 2 has a method submitChild2()
// Child 3 has to access both of those methods
class Parent1 extends React.Component {
render() {
return (
<div>
<Child1 />
<Child2 />
<Child3 />
</div>
);
}
}
class Child1 extends React.Component {
submitChild1() {
dispatch(Action1());
}
render() {...}
}
class Child2 extends React.Component {
submitChild2() {
dispatch(Action2());
}
render() {...}
}
class Child3 extends React.Component {
submitTheOtherMethods() {
// try to access Child 1 method
// try to access Child 2 method
}
render() {...}
}
You can't do this, you're going against the React design purposes which help ensure components are well designed and not tightly coupled to others.
You'll need to define the methods on the parent and pass these into the child components as properties if you want have methods to be shared between multiple different components.
The life cycle hooks will still have access to the component properties if you need to call a method within one of these.
You can achieve this behavior. Of course, the information will have to be passed around through a common ancestor (parent) of the sibling. You can do that using the useRef
hook, for example:
function App() {
const child1Method_ref = React.useRef(null);
return(
<React.Fragment>
<Child1
child1Method_ref={child1Method_ref}
/>
<Child2
child1Method_ref={child1Method_ref}
/>
</React.Fragment>
);
}
function Child1(props) {
const child1Method = React.useCallback(()=>{
console.log('I am a Child 1 method!!!');
},[]);
React.useEffect(()=>{
props.child1Method_ref.current = child1Method
},[]);
return(
<div>I am Child 1 (I declared the method)</div>
);
}
function Child2(props) {
return(
<React.Fragment>
<div>I am Child 2</div>
<button onClick={()=>props.child1Method_ref.current()}>
Click to call Child 1 method from Child 2
</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
Here is how it works:
useRef
points to an object, which the reference will be preserved across renders. I.e: the object will not change. The very same object will be accessible throughout the full lifecycle of the components.child1Method_ref
is passed down to Child1
and it runs a useEffect
to update it and stores the method
inside the current
property of the object. Obs: The useRef
object actually has a property named "current".Child2
also receive the same object through props
and can access the method from Child1 that has been stored into the ref object.useCallback
is used to keep the same reference for the function across renders. I.e: the function remains the same in this case (it's not recreated on every render).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With