Reputation: 969
I'm learning React hooks (and I'm fairly new to React), and was thinking through use cases for useImperativeHandle. I came up with a pretty useful scenario.
I do know that this can be accomplished without useImperativeHandle, but I think there are some advantages here.
What I don't know...
My code is working- but I'm looking for input about best practices. Also, since there's a dearth of information right now about useImperativeHandle, this example that goes beyond an input ref might be useful to others.
I have a minimal example posted on Github if you want to play with it: https://github.com/ericsolberg/react-uih-hook
Using markup similar to:
const App = props => {
return (
<Foo>
<Bar>This is Bar 0</Bar>
<Bar>This is Bar 1</Bar>
<Bar>This is Bar 2</Bar>
</Foo>
);
};
What I've accomplished is:
As I noted, this works perfectly. In React, data and props flow down the tree, while callbacks flow up. This gives you a way, for specific scenarios, to call down the tree. Is it advisable?
Upvotes: 2
Views: 3546
Reputation: 22324
This is an anti-pattern: Inject props into the children
without explicitly passing the props.
The idiomatic options are:
So if nothing simpler would be suitable for my business logic, I do something like following to avoid invisible tight coupling between Foo and Bar:
const App = () => (
<Foo>
{({selector, saveStateFactory}) => (<>
<Bar state={selector(0)} saveState={saveStateFactory(0)} />
<Bar state={selector(1)} saveState={saveStateFactory(1)} />
</>)}
</Foo>
)
const Foo = () => {
const [state, dispatch] = useReducer(...)
const selector = (id) => state[id]
const saveStateFactory = (id) => {
return (payload) => dispatch({type: id, payload})
}
// do something with whole state that cannot be done in App nor Bar
return children({selector, saveStateFactory})
}
Upvotes: 4