Reflect update setInterval(function()) in React Native - javascript

I'm wondering that there is a way I can make an api call with an interval and update my view whenever there is a change in api data.
part of my code looks like..
index.ios.js
....
import App from './src/components/app';
import reducers from './src/reducers';
import { getData } from './src/actions/index';
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducers, composeEnhancer(applyMiddleware(ReduxPromise, ReduxThunk)));
store.dispatch(getData());
class MyApp extends Component {
render() {
return (
<Provider store={store}>
<App />
</Provider>
);
}
}
AppRegistry.registerComponent.....
So the store.dispatch(getData()) initially make an api call and I can display the data using redux (this.props.data..something like this) in my containers.
I tried to make an api call with an interval like store.dispatch(setInterval(getData()), 30000) but it gives me an error saying undefined is not an object(evaluating 'func.apply')
If anyone has had this kind of issue before or knows what to do in this situation, please let me know.
Thanks for your support in advanced.

Related

Shallow render a component which is a class that uses context

I am trying to test a component using shallow with enzyme. The component I am trying to test is a class and doing context like so:
class ExampleComponent extends Component {
static contextType = AppContext;
...
and using it in that component const { url } = this.context;
When writing the test this has been used:
const contextWrapper = {
wrappingComponent: AppContext,
wrappingComponentProps: { url: 'http://appUrl.com' },
};
and here is the snapshot test as an example which is using mount as this seems to be the only way to get context to work.
it('should render correctly', () => {
const output = mount(<Comonent {...props} />, contextWrapper);
expect(shallowToJson(output)).toMatchSnapshot();
});
I have done some refactoring and in this file there is a component which is connected to the store. When using mount it expects a store to be provided to that component which is why I would like to us shallow.
If I wrap Component with a <Provider store={store}> I can get this to all work but I have a test further down trying to access state on Component but it is blank and can't find it.
Here is a snippet of the test where state is not found:
const output = mount(
<Provider store={store}>
< ExampleComponent {...newProps} />
</Provider>,
contextWrapper,
);
expect(output.state('stateValue')).toBe(true);
and this is the error shown:
ReactWrapper::state("stateValue") requires that `state` not be `null` or `undefined`
Is there a way to use shallow and context? I have found this package to 'fix' it for now shallow-with-context but I am not sure if that is correct? I have also seen old posts saying enzyme doesn't support the new context api. is that correct? What is the best method to solve this issue?

How to push a graphql mutation into a component's props properly?

I'm trying to push a graphql mutation into a component's props.
export default graphql(logOnMutation)(Login);
That line of code above doesn't work. No errors showing, but doesn't provide mutate function into props of component.
But if I write like that:
const logOnWithMutation = graphql(logOnMutation)(Login);
export default logOnWithMutation;
and write like this
const App = () => {
return (
<ApolloProvider client={client}>
<Fragment>
<logOnWithMutation/>
</Fragment>
</ApolloProvider>
)
}
it works perfectly.
So what am I missing? I need my first option to work
Decision:
import your Login component in your's parent component as default like that import Login from './containers/login/login'; not through the exact name like import { Login } from './containers/login/login';

Google Analytics setup for React

I have managed to set up Google Analytics for my React application with the ReactGA library so it will send the pageview to analytics when the user navigates around.
The problem
The problem I'm facing is that I'm not sending any analytics to google on the initial page load, since the history.listen method only fires when the location changes.
My setup
In the root of my project, I initialize the connection:
const history = require("history").createBrowserHistory;
import { Router } from "react-router-dom"
ReactGA.initialize(envConstants.ANALYTICS_TRACKING_ID);
const MyApp = () => (
<Router history={history}>
<MyRoutes />
</Router>
)
Since I only want to see which routes the users are on I have this in my router:
const MyRoutes = props => {
props.history.listen(location => {
// won't see this on initial load, but navigating to another route will give me this
console.log("LISTENING")
})
return (...)
}
So I wonder how I can come around this and send the first/ initial pageview when a user comes to my site. I believe I cannot achieve this with the history.listen method. So, I guess we have to add some other functionality that I'm not too sure of.
I appreciate all the help I can get with this. And if there's something unclear, please let me know.
Thanks for reading and have a nice day!
The issue is that history listen is not called on initial page load since it's only called when the location changes. Try something like the following
import { Router } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';
import ReactGA from 'react-ga';
const trackPageView = location => {
ReactGA.set({ page: location.pathname });
ReactGA.pageview(location.pathname);
};
const initGa = history => {
ReactGA.initialize('UA-XXXXXX-X', {
debug: true
});
trackPageView(history.location);
history.listen(trackPageView);
};
const history = createHistory();
initGa(history);
ReactDOM.render((
<Router history={history}>
<Layout />
</Router>
), document.getElementById('root'));

Passing data between External js and React js/Redux

I've integrated React-redux in a externalJs Application (built on custom JS framework). I need to set initial data for redux store from externalJS but, the externalJs is unable to access the react store to set the data. The store gets triggered when the root reactJS component is mounted on the DOM , but i need to set the initial data before its Mounted on the DOM. i referred following links but they were not able to resolve my problem. Can someone please tell me what I am missing?
https://brettdewoody.com/accessing-component-methods-and-state-from-outside-react/
Accessing react components outside
i'm using webpacks, react 16.1 with redux
sample root component structure given below in index.js
render() {
return (
<Provider store={store}>
<Email ref={(EmailComponent) => { window.EmailComponent = EmailComponent }} />
</Provider>
);
}
I'm assuming you're trying to expose EmailComponent and 'store' to the DOM and other frameworks since you are declaring it on a global window object. React.render has a callback as a third parameter which you can use to know when the React App is mounted to DOM.
ReactDOM.render(<App />, document.getElementById('root'), function () {
// now the root React App is mounted and the data from it will be available
// your window.EmailComponent and window.store should now be avialable
console.log(window.EmailComponent, window.store)
})
render() {
window.store = store
return (
<Provider store={store}>
<Email ref={(EmailComponent) => { window.EmailComponent = EmailComponent }} />
</Provider>
);
}

How to test a component with a nested container with React and Redux?

Due to the complexity of the application I am working on I have decided on using a nested redux container rather than passing an action as a prop down to the child components. However, this has proved to be problematic for unit testing when rendering the OuterContainer with jsdom in combination with mocha, chai and sinon.
Here is a contrived example of the view structure:
<OuterContainer>
<div>
<InnerContainer />
</div>
</OuterContainer>
where OuterContainer & InnerContainer are wrapped with connect. e.g.:
export connect(<mapStateToProps>)(<Component>)
When running tests the error I am getting is:
Invariant Violation: Could not find "store" in either the context or props of "Connect(Component)". Either wrap the root component in a `<Provider>`, or explicitly pass "store" as a prop to "Connect(Component)".
Is there a way to unwrap or stub the InnerContainer for unit testing without having to use shallow rendering?
Wrap your component in <Provider> when testing. It’s up to you whether to supply a real store or a mock with { dispatch, getState, subscribe } to it. Wrapping the outermost component in <Provider store={store}> will also make the store available to the child components at any level of nesting—just like in the app itself.
const store = createStore(reducer) // can also be a mock
ReactTestUtils.renderIntoDocument(
<Provider store={store}>
<OuterContainer />
</Provider>
)
Another approach is to export both the component to be connected and the container. The container as default, of course.
export const Comp = (props) => (<p>Whatever</p>)
export default connect(...)(Comp)
Hence, you can unit test Comp.
Not sure if this is what your problem is, but I'm sure this will probably help a few people out there looking at this feed.
I had the same error and it was a simple fix:
I had forgotten to pass my component my store object in my entry file (using webpack).
I just added an attribute to the Root component "store={store}" see below:
document.addEventListener("DOMContentLoaded", () => {
const store = configureStore();
ReactDOM.render(<Root store={store} />,
document.getElementById('content'));
});
This was my root file code for reference as well:
import React from 'react';
import { Provider } from 'react-redux';
import App from './app';
const Root = ({ store }) => (
<Provider store={ store }>
<App />
</Provider>
);
export default Root;
Hope that helps someone!
Mock the Provider component to return the child component.
Add this before describe().
jest.mock('Provider', () => ({children}) => children);

Categories