Flux threw Dispatcher is not a constructor - javascript

I try to use jspm with reactjs. I worked fine. But when I integrated it with flux package from npm. Then it always threw Dispatcher is not a constructor error.
My code as below
AppDispatcher.js
import Flux from 'flux';
export default new Flux.Dispatcher();
StoreBase.js
'use strict';
import {EventEmitter} from 'events';
import AppDispatcher from '../dispatchers/AppDispatcher';
const CHANGE_EVENT = 'change';
export default class BaseStore extends EventEmitter {
constructor() {
super();
}
subscribe(actionSubscribe) {
this._dispatchToken = AppDispatcher.register(actionSubscribe());
}
get dispatchToken() {
return this._dispatchToken;
}
emitChange() {
this.emit(CHANGE_EVENT);
}
addChangeListener(cb) {
this.on(CHANGE_EVENT, cb)
}
removeChangeListener(cb) {
this.removeListener(CHANGE_EVENT, cb);
}
}
I used reactjs#0.13.3, react-router#0.13.3 and flux#2.0.3. Could anyone help me on this?

If you are using Babel you can use below
import { Dispatcher } from 'flux';
const dispatcher = new Dispatcher();
export default dispatcher;

You should export the Dispatcher as follows
import Flux from 'flux';
export default new Flux.Dispatcher;

Related

React Native: use mobx store state from another store

I was wondering how can I use a n observable from one store inside another store class, for example use userStore inside mapStore.
Now I will show you how I initiate stores and use them in my functional components:
/contexts/index.js
import React from 'react'
import { configure } from 'mobx';
import { UserStore } from '../stores/UserStore.js'
import { MapStore } from '../stores/MapStore.js'
export const storesContext = React.createContext({
userStore: new UserStore(),
mapStore: new MapStore(),
});
configure({ enforceActions: "observed" });
/hooks/use-stores.js
//hooks/use-stores.js
import React from 'react'
import { storesContext } from '../contexts/index.js'
export const useStores = () => React.useContext(storesContext);
Inside my functional components I access like this:
import { useStores } from '#hooks/use-stores';
...
const { mapStore,userStore } = useStores();
An example class, UserStore
export class UserStore
{
constructor()
{
makeAutoObservable(this);
user = false;
}

Using React Router from a non-react class

I have a manager class in my app that is just a regular JS class, it's purely logical with no view. I use an instance of it in several of my components. For one of it's actions I'd like it to change the route in my React based app. I know I can return something to each component and then have the component do the routing, but I'd like to know if there is a way to do it from my non-react class. Is there maybe a way to pass in the history object and push the new route to it?
Thanks for any help.
EDIT: It's more of a theoretical/methodolgy question but for example:
Manager class:
class MyManagerClass {
constructor() {
this.data = {...some internal data};
}
doSomething(param) {
if(this.data[param]) {
this.data[param]();
} else {
//here i'd like to change the route in my react app
}
}
}
Component:
import React, {useContext, useEffect, useRef, useState} from "react";
const MyComponent = props => {
const myManagerClass = new MyManagerClass();
useEffect(() => {
myManagerClass.doSomething('param');
}, [props.something]);
return (
<div>Component</div>
)
}
There are minimum 2 solutions to this
SOLUTION 1:
You can pass the history object to the action as argument from the component
class Util {
static someAction(history) {
history.push('/someurl');
}
}
and call it like
const Comp = () => {
const history = useHistory();
const someHandler = () => {
Util.someAction(history);
}
...
}
SOLUTION 2:
Use a custom history for Router and then you can import history directly into the class file
history.js
import {createBrowserHistory} from 'history';
export const history = createBrowserHistory();
use it for Router like
import { Router } from 'react-router-dom';
import { history } from './path/to/history';
...
return (
<Router history={history}>{/* Routes here */}</Router>
)
and then in your Class file
import {history} from '/path/to/history';
class Util {
static someAction() {
history.push('/someurl');
}
}

Javascript module import fails - why?

I'm a javascript newbie and I'm trying to figure out why this import statement fails. I don't know if this is relevant but I'm doing this in the context of a Create React app with its default webpack setup. I have these files:
TestClass.js
export default class TestClass {
sayHello() {
console.log("Hello World.");
}
}
TestModule.js
import TestClass from "./TestClass";
module.exports = {
MyExport: {
doSomething: function() {
let testClass = new TestClass();
testClass.sayHello();
}
}
}
And then my main React Application file, App.js:
import React, { Component } from "react";
import "./App.css";
import { MyExport } from "./TestModule"
class App extends Component {
constructor(props) {
super(props);
MyExport.doSomething();
... bla bla bla ...
}
When I attempt to run this in Node.js, it returns
Failed to compile.
./src/App.js
Attempted import error: 'MyExport' is not exported from './TestModule'.
What am I doing wrong?
You are mixing es6 modules with Commonjs style imports. Your TestModule should be exported as follows:
import { TestClass } from "./TestClass";
export const MyExport = {
doSomething: function () {
let testClass = new TestClass();
testClass.sayHello();
}
};
This should work while allowing the rest of your code to remain the same
You can try this:
import { TestClass } from "./TestClass";
const Object = {
MyExport: {
doSomething: function() {
let testClass = new TestClass();
testClass.sayHello();
}
}
}
export default MyExport
As you are using two different type of import export
Or if you have to use module.exports you can try this:
import { TestClass } from "./TestClass";
module.exports = function () {
return {
MyExport: {
doSomething: function() {
let testClass = new TestClass();
testClass.sayHello();
}
}
}
}
You can try exporting function instead of object

React import module error

Simply what im trying to do is export a function that make a mongodb query and import it into a react component so i can call it there and display the data.
this is the error i keep getting: ./node_modules/require_optional/node_modules/resolve-from/index.js
Module not found: Can't resolve 'module' in '/Users/paul/Desktop/TempProject/Dietx/dietxweb/node_modules/require_optional/node_modules/resolve-from'
react component, Diet.js:
import React, {Component} from 'react';
import getItemList from '../server/api.js';
import ReactList from 'react-list';
class Diet extends Component {
constructor(props){
super(props)
this.state ={
Calories : 3000,
Items: [],
}
}
componentWillMount(){
}
render(){
return(
<div className="diet-container">
<p>lol</p>
</div>
)
}
}
export default Diet;
API, api.js:
const mongo = require('mongodb');
export const getItemList = ()=>{
var url = "mongodb://localhost:27017/food"
return(
mongo.connect(url)
.then((db)=>{
return db.collection('foodInfo')
})
.then((res)=>{
return res.find().toArray()
})
)
}
Change
export const getItemList = ()=>{
to
export default function getItemList() {
The syntax you are using is importing the default member from the module but your module does not define a default member.
Alternatively, you could use the syntax
import {getItemList} from ...

MobX + React Native : way to inject stores

I'm trying to work with MobX for a new project.
I started it on May 2017, and everything was working well. I had to stop, and now I go on developing it. I had to make an npm install to manage making it working, but now, I have some problem with stores...
I rely on this tutorial for the structure : https://blog.callstack.io/write-react-native-apps-in-2017-style-with-mobx-e2dffc209fcb
This is my structure :
Main index.js
import { Provider } from 'mobx-react';
import Stack from './router';
import stores from './stores';
export default class App extends Component {
render() {
return (
<Provider {...stores}>
<Stack />
</Provider>
);
}
}
Index.js of my stores in ./stores/index.js
import ChatStore from './ChatStore';
import UserStore from './UserStore';
export default {
UserStore: new UserStore(),
ChatStore: new ChatStore(),
};
./stores/UserStore.js (important parts)
import { observer, inject } from 'mobx-react';
import {autobind} from 'core-decorators';
...
#inject(['ChatStore'])
#observer
#autobind
export default class UserStore {
#observable isAuthenticated = false;
#observable isConnecting = false;
#observable user = null;
#observable messages = [];
#observable hasMoreMessages = false;
#observable skip = 0;
...
login() {
const payload = {
strategy: 'local',
material_id: DeviceInfo.getManufacturer(),
password: DeviceInfo.getManufacturer()
};
return this.authenticate(payload);
}
...
Now, for components part :
Router.js
import { StackNavigator } from 'react-navigation';
import Home from './containers/Home';
const stackNavigatorConfig = {
initialRouteName: 'Home',
};
export default StackNavigator({
Home: {
screen: Home,
},
}, stackNavigatorConfig);
./containers/Home.js
import React, { Component } from 'react';
import { AsyncStorage } from 'react-native';
import { observable } from 'mobx';
import { observer, inject } from 'mobx-react';
#inject('UserStore')
#observer
export default class Home extends Component {
props: Props;
...
render() {
this.props.UserStore.login().catch(error => {
console.log('LOGIN', 'ERROR', JSON.stringify(error), error.message);
});
return {
...
}
}
And then, I get an error :
So, I sum up :
I use <Provider> from MobX, to give all my stores to my app
Then, I get the Store I want in my component with #inject
I use it as a props, using this.props.UserStore...
But it does not work. I rely on this tutorial for the structure : https://blog.callstack.io/write-react-native-apps-in-2017-style-with-mobx-e2dffc209fcb
Maybe there was an update between May 2017 and today, that makes things different... It was working well on May 2017.
I think this is a dummy error, but I can't find which one...
Everything looks good except the decorators on your UserStore class: #inject(['ChatStore']) #observer #autobind. #inject(['ChatStore']) #observer is used on React components, #autobind might still work as intended.
It should work if you remove those.
maybe worth using #action from mobx

Categories