Reputation: 1781
I have a function responsable for setting a height dynamically to an element, this function is being triggered from multiple components, some of them are children of the component which has the function and other aren't.
This implies two problemas, concerning the children components I have to pass the function down the tree for multiple levels as a callback, and about those that are not children I have to use document.getElementById
to access the element, what is not ideal when it comes to react, besides that I have to build the same function for every non-chldren component.
In order to make things more clean and maintainable I converted the funtion to a hook that makes this DOM manipulation (this is a hook and not a common function, because I need to call another hook from it), but I still have to use document.getElementById
to access the target element.
What I want to do is if is there a more react way for accessing the element? Like accessing a ref
from a component outside the tree for instance?
Upvotes: 1
Views: 316
Reputation: 24661
Create a context:
height-context.jsx
const HeightContext = createContext();
export const HeightContextProvider = ({ children }) => {
const [height, setHeight] = useState();
return (
<HeightContext.Provider value={{ height, setHeight }}>{children}</HeightContext.Provider>
)
}
const useHeightContext = () => {
const context = useContext(HeightContext);
if (!context) throw Error('HeightContext must be used within HeightContextProvider ');
return context;
}
app.jsx
(or any other component that is a common ancestor of component P and O)
const App = () => {
return (
<HeightContextProvider>
// other components
</HeightContextProvider>
)
}
child.jsx
(or any component where you will change height)
const Child = () => {
const { setHeight } = useHeightContext();
return (
<button onClick={() => setHeight(100)}>change height</button>
)
}
manipulated-component.jsx
const ManipulatedComponent = () => {
const { height } = useHeightContext();
return (
<div style={{ height }}>
//other components
</div>
)
}
Upvotes: 1