React native redux export default connect - javascript

I do not want to separate components when I am using react-navigation with redux.
How can I make a "const=" rather than make a new file and "export default"
const IntroScreen2 =connect(mapStateToProps,mapDispatchToProps)(IntroScreen2a)
const IntroScreen2 =()=> connect(mapStateToProps,mapDispatchToProps)(IntroScreen2a)
export default connect ...
which one is right?
https://codeshare.io/G79NRk

Do it something like this, define the component in the same file as where you use a default export of connect, passing in the component defined in the file.
These statements should help clear up your misunderstanding(s).
With react navigation, you have screens (components), and you have navigators. Navigators are created with screens (components).
You use react-redux's connect function to connect components to the redux store. You simply wrap a component in a call to connect, and export the return value of that, rather than the component itself.
When you create a navigator, you will need to import the components for your screens.
See the follow three pages, we make a component, export the component connected to the redux store, via react-redux's connect function.
Then we make a router, which exports a single stack navigator from react navigation, which defines a single screen, the component defined (mentioned above).
Then I have given an example of how you'd render that router, for example, inside your App.js.
some-component.js
import React, {Component} from "react";
import {connect} from "react-redux"
// Define the component
class SomeComponent extends Component {
render() {
return null;
}
}
// Map dispatch to props
const mapDispatchToProps = (dispatch) => {
return {};
}
// Map state to props
const mapStateToProps = (state) => {
return {};
};
// Export the component, passed into the connect function from react-redux.
export default connect (mapStateToProps, {}) (SomeComponent);
Then just import this file when defining your navigator with react navigation.
For example
router.js
import SomeComponent from "./some-component.js";
import {createStackNavigator} from "react-navigation";
export default createStackNavigator({
PageOne: {
screen: SomeComponent
}
});
In your App.js (root level)
import React, {Component} from "react";
import Router from "./router.js";
export default class App extends Component {
render () {
return <Router/>;
}
}
Something like that should get you sorted!

Related

Why can't I consume MyContext in App Component?

import React, { useContext } from "react";
import { ContextProvider, MyContext } from "./Context/MyContext";
import "./styles.css";
export default function App() {
const value = useContext(MyContext);
console.log(value);
return (
<ContextProvider>
<div className="App">{value}</div>
</ContextProvider>
);
}
If I want to consume the useContext exactly on App Component. I get the value as undefined on App Component but the value of all other component is okay. So, I want to know what is the mechanism behind it. Why I can't access to useContext in App component.
The ContextProvider provides the values within your Context to all it's child components. The value you are supplying to your <div> comes from the parent component of ContextProvider in your case, ie the App. At this point your Provider has still not been set up, you have to wrap App inside provider to access the values of the context. In other words the Provider needs to be the Parent of app to provide it values and not the other way around

Pass react-redux store and dispatch functions via props?

The following React component is given:
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { store, StoreState } from "../../redux/actions";
import { setBackgroundAction } from "../../redux/title.actions";
import "./Loader.scss";
interface ReduxProps {
bgClass: string;
}
interface Props extends ReduxProps {
bgChange?: boolean;
}
export default function Loader(props: Props) {
const [bgClassOld, setBgClassOld] = useState<string>("");
const dispatch = useDispatch();
useEffect(() => {
const { bgChange, bgClass } = props;
if (bgChange) {
setBgClassOld(bgClass);
dispatch(setBackgroundAction("bg-white"));
dispatch(setBackgroundAction(bgClassOld));
}
});
return (
<div className="d-flex">
<div className="loader">
<img src="/loadscreen.gif" />
</div>
</div>
);
}
// function mapping(state: StoreState): ReduxProps {
// return {
// bgClass: state.title.backgroundClass,
// };
// }
This is more a theoretical question to see how to actually do the following change:
The component Loader will be imported from another npm package (shared components).
My problem is that I have a redux state in the current implementation included (changed it from Class to Functional component, so thats mapping() is still in there).
As I only import the component in my "main" client, I will not have the whole redux setup in place. So I think I need to pass the store and the dispatch functions via props.
So should I create a prop store for my component, where I pass the redux store when I import the shared component?
Do I also create two props for each dispatch functions?
Does is make sense or would there be a better approach?
You generally shouldn't import the Redux store directly into components. The hooks allow your component to access whatever Redux store has been injected into the component tree by a <Provider>.
You also don't need to pass dispatch as a prop. Any component can call useDispatch(), and dispatch actions to whatever Redux store is actually being used.
If I understand your question, you're planning on importing this component into an existing app, and it sounds like that app is already configured to use (React-)Redux with a <Provider> at the top. If that's the case, then you don't have to do anything else special to make this work. Just call the React-Redux hooks in any of your components.

Error in App class when using React-Redux "connect "

I am receiving the following error when trying to use the connect() function from react-redux:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of `App`.
This is App:
import { Provider } from 'react-redux';
import configureStore from './store';
const App = class extends React.PureComponent {
render() {
const { title } = this.context;
return (
<div className="center-screen">
{title}
<Provider store={configureStore()}>
<Chat />
</Provider>
</div>
);
}
};
This is the relevent code end of chat:
import { connect } from 'react-redux';
...
const mapStateToProps = state => ({
...state
});
const mapDispatchToProps = dispatch => ({
addMessage: () => dispatch(addMessage)
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Chat);
When using : "export default Chat" instead of connect, it's working fine..
Try this:
const ConnectedChat = connect(
mapStateToProps,
mapDispatchToProps
)(Chat);
export default ConnectedChat;
Or you may wish to rename the class definition to ConnectedChat and reverse the names so you can import it as just Chat.
Edit: Also make sure you're importing the Chat component in the App file, as well as the addMessage action creator if you're not.
Where are you defining Chat the component in your connect function?
My usual set up is (I'm using class but const ConnectedChart() would still be this same set up)
class ConnectedChart extends Component {
//// All code here render and return etc
}
const Chart = connect (mapStateToProps)(ConnectedChat);
export default Chart;
So that way you are essentially assigning a component to Chart with the connect statement and then you export default. I think exporting the connect statement directly might by throwing an error but if that doesn't work post the full chart component and I'll see if there is something else going on
EDIT: based on the full code
try this in your App.js:
import React from "react";
import ReactDOM from 'react-dom';
import "./App.css";
import ConnectedChat from "./Chat";
import { Provider } from "react-redux";
import configureStore from "./store";
ReactDOM.render(
<Provider store={configureStore()}>
<ConnectedChat />
</Provider>
);
and then put your div center screen in ConnectedChat
(if you are going to be adding more components later and want that div wrapping all of them, create a main app component like landing or something and call that between your provider instead of chat, and then in that landing component render the div and your ChatComponent)
Also if you don't have an index.js change the 'main' in your package.json to this App.js component

In react-admin get access to redux store

My question is related to react-admin repo.
I want to dispatch an action, outside of scope of a component, in order to do that, I've read that I need to get access to the actual redux store itself, and dispatch on in directly,
so I know that the Admin component has an initialState prop, but it only accepts default state object, not the store. So I can't make a store and pass it in.
My question is:
How do I access redux store of an Admin component?
How can I dispatch an action outside of a component, when using Admin as my main app component?
my current app entry looks like this:
<AppLayoutDirection>
<Admin
title="My App"
locale="en"
dataProvider={dataProvider}
authProvider={authProvider}
i18nProvider={i18nProvider}
theme={themeProvider}
customSagas={customSagas}
appLayout={AppLayout}
>
{DynamicResource}
</Admin>
</AppLayoutDirection>
When you say that you need to dispatch an action outside the scope of a component, I suppose that it's in reaction to another action that was dispatched in the past.
In that case, that's what react-admin calls a side effect. React-admin handles side effects using redux-saga. Here is how to create a custom saga:
// in src/bitcoinSaga.js
import { put, takeEvery } from 'redux-saga/effects';
import { showNotification } from 'react-admin';
export default function* bitcoinSaga() {
yield takeEvery('BITCOIN_RATE_RECEIVED', function* () {
yield put(showNotification('Bitcoin rate updated'));
})
}
Register this saga in the <Admin> component as follows:
// in src/App.js
import React from 'react';
import { Admin } from 'react-admin';
import bitcoinSaga from './bitcoinSaga';
const App = () => (
<Admin customSagas={[ bitcoinSaga ]} dataProvider={simpleRestProvider('http://path.to.my.api')}>
...
</Admin>
);
export default App;
This is documented in the react-admin documentation, in the <Admin> chapter.
You could also simply use custom reducers if the computation is no async
// in src/App.js
import React from 'react';
import { Admin } from 'react-admin';
import reducers from './reducers';
const App = () => (
<Admin customReducers={customReducers} dataProvider={simpleRestProvider('http://path.to.my.api')}>
...
</Admin>
);
export default App;

React Navigation - Pass props into Navigator

My React Native app has several conditions in which it needs to handle deep links when the user clicks on a link for an invite. My intent was to setup the Link listeners in the main app.js file and when a deep link is detected I need to pass the data into the Splash view to determine several factors before adding the user to the group they are invited to.
I am using React Navigation. I initially tried to use redux by updating the store with the url data but ran into timing issues as the Splash page was loading before redux was updated. So I have attempted to create an HOC wrapper for the Navigator as follows:
HOC Linker:
import * as React from "react";
const Linker = (Component) => {
return ({ children, ...props }) => {
return (
<Component { ...props }>
{ children }
</Component>
);
}
};
export default Linker;
In my App JS file I import the Linker and wrap the main navigator with the HOC component. I then add a prop that is updated when React Native Linking method detects a deep link. It updates state with the parameters.
App JS:
import Navigator from './ui/navigation/navigator';
const LinkerWrapper = Linker(Navigator);
render() {
return (
<LinkerWrapper linking={this.state.url} />
);
}
My Navigator file looks as follows:
Navigator:
import { createSwitchNavigator } from 'react-navigation';
import Splash from '../screens/splash/splash';
import AuthStack from './auth';
import AppStack from './app';
const Navigator = createSwitchNavigator({
Loading: Splash,
Auth: AuthStack,
App: AppStack
});
export default Navigator;
When I click on a deep link the app opens as expected, I parse the url and prep the data object, state is updated and the splash page is re rendered as expected, the props are passed through the HOC, but when the componentWillReceiveProps method is ran in the Splash page I do not see any props from the linking prop.
I have tried many different things. I am really new to react so I know I am probably doing something fundamentally wrong. I am guessing I am missing something with React Navigation. One of the things I tried was to change the screen value to a function passing in the props. I was hoping that would magically make the linking prop appear in the Splash page props. Below was my attempt:
import React from 'react';
import { createSwitchNavigator } from 'react-navigation';
import Splash from '../screens/splash/splash';
import AuthStack from './auth';
import AppStack from './app';
const Navigator = createSwitchNavigator({
Loading: {
screen: props => <Splash { ...props }/>
},
Auth: AuthStack,
App: AppStack
});
export default Navigator;
Unfortunately that didn't work. Any assistance would be appreciated.
Thanks.

Categories