I tried add merge props to connect
export default compose(
withStyles(styles, { withTheme: true }),
connect(
mapStateToProps,
mapDispatchToProps,
mergeProps
)(MyComponent)
But it throw TypeError: Cannot read properties of undefined (reading 'root')
when i use connect without mergeProps, it works fine
You need to show the actual functions for each of those parameters. Look into https://react-redux.js.org/api/connect#connect-parameters As you can see those parameters are functions. Maybe it will help showing your functions?
Related
I don't know how to compose Redux with onClickOutside HOC in my component export...
I tried sth like this but didn't work
export default compose(
connect(null, mapDispatchToProps),
onClickOutside)
(DropMenu, clickOutsideConfig);
Error I got :
TypeError: Cannot read property 'isReactComponent' of undefined
You can solve this problem without using the redux compose method. Try something like the following:
export default connect(null, mapDispatchToProps)(onClickOutside(DropMenu))
Not sure what you're trying to do with the clickOutsideConfig, but you can always pass it in as props to DropMenu.
So I'm trying to put together this app, using firebase and redux for storage, and Material UI as the design. I've got the firebase and firestore reducers working and all, I just run into an issue when I try to export a component using both firebase and withStyles();
(It works separately, just throws an error when I try to use both.)
Here's what I've tried:
This works, but the withStyles() is not there.
export default compose(
firebaseConnect([{ collection: 'clients' }]),
connect(mapStateToProps),
)(Clients);
This works, but it's not connected to firebase.
export default connect(mapStateToProps)(withStyles(styles)(Clients));
I've tried combining them, but each one throws an error.
export default compose(
firebaseConnect([{ collection: 'clients' }]),
connect(mapStateToProps),
)(withStyles(styles)(Clients));
export default compose(
firebaseConnect([{ collection: 'clients' }]),
connect(mapStateToProps),
withStyles(styles, {
name: 'Clients',
}),
)(Clients);
The error thrown is Uncaught Error: Path is a required parameter within definition object
Any help would be greatly appreciated. Thank you!
OK, after some messing around, I figured it out. I have to place the firebaseConnect() inside of the connect, where the actions would usually go.
const withFirebase = firebaseConnect([{ collection: 'clients' }]);
export default connect(mapStateToProps, withFirebase)(withStyles(styles)(Clients));
I'm new to redux and try to use it with Typescript.
I use mapDispatchProps for connect() in the component, when import this component, it requires to pass actions as props which it shouldn't.
The weird thing is when I tried with other actions, it seems fine, but just something wrong with this one.
The full code is
here
and the error message in index.tsx, where I want to import component.
Error message
Property 'getInputUserName' is missing in type '{}' but required in type 'Readonly>'.ts(2741)
App.tsx(8, 3): 'getInputUserName' is declared here.
Really happy to hear any advice.
Thanks in advance!
You should pass the action with same name as it is declared in the Props interface.
So either try this -
export default connect(
mapStateToProps,
{ getInputUserName: loginUserName }
)(App)
or this -
interface Props {
inputUserName: string;
loginUserName: typeof loginUserName;
}
Can you try this,
export default connect(
mapStateToProps,
{ getInputUserName: loginUserName }
)(App);
Cheers,
From version 6, with React 16.3, react-redux add support for Context API.
// You can pass the context as an option to connect
export default connect(
mapState,
mapDispatch,
null,
{ context: MyContext }
)(MyComponent)
// or, call connect as normal to start
const ConnectedComponent = connect(
mapState,
mapDispatch
)(MyComponent)
// Later, pass the custom context as a prop to the connected component
;<ConnectedComponent context={MyContext} />
I'm migrating my app, but there are so many places need to add the MyContext, do we have some ways to safely add it for every ConnectedComponent in only one place?
Passing a context explicitly to Redux Provider and connect is only needed if multiple nested stores have to be used, as described in this answer. This is a replacement for deprecated store option in connect.
If there multiple components that need to be connected with same custom context, helper HOC can be created:
const myConnect = (mapStateToProps = null, mapDispatchToProps = null, mergeProps = null, options = {}) => (
connect(mapStateToProps, mapDispatchToProps, mergeProps, {...options, context: MyContext })
);
If there's the only store or they don't intersect, custom context can be omitted, default Redux context will be used instead.
In our application we use i18next (exposing the HOC withNamespaces) and material-ui (exposing the HOC withStyles) and we have to use typescript. Some components need both translations and styling, so they have props like
interface MyCompProps extends WithStyles, WithNamespaces {
// actually relavent props here
}
and are exported with both HOCs
export default withStyles(styles, { withTheme: true })(withNamespaces()(MyComp as any)) as typeof MyComp;
This has some problems, for example:
Nesting the function calls like that is unreadable
We need two casts (as any, as typeof MyComp) for this to work, otherwise we get type-errors. Sometimes we still get type-errors after casting.
If we had plain JS I'd write
export default compose(
withStyles(styles, { withTheme: true }),
withNamespaces()
)(MyComp)
But in TS this function returns a {} instead of a typeof MyComp (without WithStyles and WithNamespaces) as I'd expect.
I can force it to be a typeof MyComp, but then the usage of this component complains that I don't set the fields for WithStyles and WithNamespaces.
How do I compose these HOCs so that the resulting type is correct?
As far as I understand the resulting type should be ComponentClass<MyCompProps> without the fields of WithStyles and WithNamespaces.