Giter Site home page Giter Site logo

keajs / kea Goto Github PK

View Code? Open in Web Editor NEW
1.9K 31.0 51.0 7.43 MB

Batteries Included State Management for React

Home Page: https://keajs.org/

License: MIT License

JavaScript 59.68% TypeScript 40.32%
react redux kea sagas react-component framework data redux-saga redux-thunk

kea's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kea's Issues

Integration with ReactQL

Currently I'm using ReactQL for my go-to starter as it offers a seemless development environment for React/Redux/Apollo/Webpack stack

from their documentation:

ReactQL is React + GraphQL done properly — for Mac, Windows and Linux.

It combines best-of-breed choices for UI, GraphQL data fetching, CSS and code bundling, > handles server-side rendering (SSR) properly, and is fast and extensible. You can choose Javascript or Typescript flavours.

It focuses on performance characteristics that you don't often find in other starter kits — offering Zopfli/Brotli compression, automatic vendor splitting, aggressive minification of JS/CSS, instant hot code reloading and more, out-the-box.

It pairs an async web server for handling SSR, non-JS imports (like images, CSS, etc) and works universally. Your code will run both in the browser, and on the server — even inline imports!

Development, production and even static bundling can be invoked with just one command, via the ReactQL CLI.

You can easily bolt-on your own GraphQL server, or point to one off-site.

If you want to shave weeks off your next project boilerplate, try ReactQL.

If you could help me to get it working, i'll try to submit a PR on reactql kit repository and convince the ReactQL author to get it officially supported.

The kea starter kit is good, but I believe if we could get more boilerplate to use Kea, it will bring more attention to the community and more people will start using the library.

This is what I have so far:
wmhafiz/reactql-kea#1

It seems to be working, except there's an error in the console log

[KEA-LOGIC] Path starting with "scenes" is not connected to the reducer tree! (3) ["scenes","counter", "index"]

Screenshot

Any idea where did i do wrong?
Thanks!

Looking to integrate with Redux-PouchDB-Plus

I'm looking at using redux-pouchdb-plus for persistence. The integration requires wrapping persistentReducer around reducers to be saved to the db. Looking for suggestions on how to do that with reducers generated by Kea.

Separate CLI from core library

Currently commander is listed as a dependency. Would it make more sense to move this and other CLI related libs into a separate repo kea-cli so these do not get bundled with production builds?

Also, is there a reason why this library is including a specific hash?
tj/commander.js#c6236d9504b60d9a2e6aa7fc3ce17a12f48f4a3e
It is giving me issues when trying to add it with yarn behind a corporate proxy.

Thanks!

Starting a new kea app from scratch with Windows does not work

Creating a new application according documentation "Starting a new kea app from scratch" with Windows 10 gives an error about rm-command which obviously is not available from Windows command prompt.
Given command and error are as follows:
C:\temp\foobar>kea new my-project
Creating new project "my-project" with template "default" (keajs/kea-example)
--> Running: git clone --quiet --depth=1 --branch=master https://github.com/keajs/kea-example ./my-project && rm -rf ./my-project/.git
'rm' is not recognized as an internal or external command,
operable program or batch file.
child_process.js:524
throw err;
^

Error: Command failed: git clone --quiet --depth=1 --branch=master https://github.com/keajs/kea-example ./my-project && rm -rf ./my-project/.git
'rm' is not recognized as an internal or external command,
operable program or batch file.

at checkExecSyncError (child_process.js:481:13)
at execSync (child_process.js:521:13)
at Object.<anonymous> (C:\Users\foo\AppData\Roaming\npm\node_modules\kea\lib\cli\kea-new.js:50:1)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.runMain (module.js:605:10)
at run (bootstrap_node.js:427:7)

connect - import all the props from a reducer?

Two questions,

  1. How do I import everything from a reducer/actions?
  2. put them into it's own object instead of everything in this.props

Eg,

// if task reducer had following properties
{
  data: [],
  loading: false
}

@connect({
  actions: [
    session, ['storeSession'],
    tasks, ['*']
  ],
  props: [
    session, ['isLoggedIn'],
    tasks, ['*']
  ]
})

//somewhere in component, I should be able to use like this:
this.props.tasks.data;
this.props.tasks.loading
this.props.session.isLoggedIn
this.actions.session.login();
this.actions.tasks.load();

Export workers for tests

Right now:

const logic = kea({
  workers: {
    * doSomething () {
      // ...
    }
  }
})

console.log(logic.workers) // undefined

In order to test your workers, you should be able to access them.

How to access current props from a selector?

I'm trying to create a selector that takes an id that is passed to the component through props and uses that id to pull the object out of a kea reducer that has that id. This is a case where i want to use a selector but I can't figure out how to make the selector get recalculated whenever the prop changes.

Here's an example to demonstrate what i'm trying to accomplish. There is a books reducer that has a dictionary of books based on their id.

books = {
    0: { title: "My Book" },
    1: { title: "My Other Book" },
}

Now I have a component that gets passed a book id:

<BookDetail bookId={0} />
<BookDetail bookId={1} />

I want to intercept the bookId that was passed to BookDetail and inject a book prop. However, the selector i have defined doesn't get called for each BookDetail component. It only gets called once because the input selector hasn't changed. The only input selector is the books reducer, which hasn't changed in this case. Is there a way to tell kea to reevaluate a selector when a prop changes?

@kea({
  reducers: ({ actions }) => ({
    books: [null, PropTypes.object, {}],
  }),
  selectors: ({ selectors, props }) => ({
    book: [
      () => [selectors.books],
      books => books[props.bookId],
      PropTypes.object,
    ],
  }),
});

Any help you can give would be appreciated. I've liked kea so far but it feels like what i'm trying to do shouldn't be difficult because it's so easy to do with reselect.

TypeError: reactRedux.connectAdvanced is not a function

Hi, i want to use kea v0.23.2 in a existing redux-project, but i'm getting the next error:
captura de pantalla de 2017-09-13 16-42-22
captura de pantalla de 2017-09-13 16-26-11

Then i update the kea package to v0.24.1 and now when i try to use 'connect' function i'm getting this error:
captura de pantalla de 2017-09-13 17-22-35

captura de pantalla de 2017-09-13 16-46-14

Thanks for advanced.

can getState accept an initialState as one of the Options?

Looking at the code for getState I noticed initial state can not be passed, this forces me to rely on the manual method for setting up my store, is there a specific philosophy behind this?

I need it for both mocking the store in react-cosmos as well as server side rendering.

Uniform way to extend logic creators

Unrelated - any preferred ways to extend kea logic in a uniform way without creating an instance first? Something like there is a "logic creator" function in a "Form" tutorial in the docs, but with a way to override / add to everything? I realize it can become cumbersome with the way we define connections in kea (array > array > syntax-reach string).

Extend === override actions / reducers / sagas / workers / connect

Separate Kea from Redux Saga

Hi there!

I'm using Kea at work with Relay Modern and I noticed that Kea has a dependency on Redux Saga. I think it would be better to have the Redux Saga support as a separate package in case that a user has a different async library.

Redux-observable?

Any thought on adding redux-observable support?

Could look something like:

@kea({
    key: (props) => props.id,

    path: (key) => ['scenes', 'homepage', 'slider', key],

    actions: () => ({
        updateSlide: index => ({ index })
    }),

    reducers: ({ actions, key, props }) => ({
        currentSlide: [props.initialSlide || 0, PropTypes.number, {
            [actions.updateSlide]: (state, payload) => payload.key === key ? payload.index % images.length : state
        }]
    }),

    selectors: ({ selectors }) => ({
        currentImage: [
            () => [selectors.currentSlide],
            (currentSlide) => images[currentSlide],
            PropTypes.object
        ]
    }),

    epic: (action$, store, selectors) => action$
        .ofType(SOMETHING_INIT)
        .map(() =>
            selectors.getSlideImages(store.getState()) 
        )
        .map(images => ({
            ...images,
            ...getSlideMetaData(store.getState(), images.cardSelection)
        }))
        //..etc...
})

Simple `mapStateToProps` conundrum

Ok, here is the case. And please correct me if I'm trying to achieve this the "wrong way".

I have an auth logic which looks something like this:

// logic/auth.js

export default koa({
  // ... actions, path, etc.
  reducers: ({ actions }) => ({
    user: [null, PropTypes.object, {
      [actions.setUser]: (_, user) => user,
    }],
  }),
});

Then I want to have a HOC which is called CheckPermissions and it should, given the permissionsCheckCallback, render children only if the provided function returns true.

Now, the way I would go about it with vanilla redux is to have the CheckPermissions component connected with the store by giving it a mapStateToProps function which would:

  • take the user from the provided state
  • take the permissionsCheckCallback function from ownProps
  • return { hasPermissions: permissionsCheckCallback(user) }

This way component is never rerendered even if the user changes but the permissions stay the same (optimal).

Now, I've started doing this in kea by having the CheckPermissions component (pure function really...) export this:

// components/CheckPermissions.jsx

import Auth from '../logic/auth';
import { connect } from 'kea';

export default connect({
  props: [
    Auth, [
      'user',
    ],
  ],
})((props) => (
  props.hasPermissions(props.user)
  ? props.children
  : null
))

But, the mapStateToProps concept is happening inside the component, not outside so it does not stop the "rerender" cycle: if the user changes - even if the permissions do not - it will trigger the render.

Now, either I'm not reading the docs right / not getting some core concept of kea or this is not possible to do the kea way? Sure, I can always target the user from the global state (no need to even connect Auth) but this is why I'm trying to use kea, so I don't have to think about the "global" state and bring "logic" as needed (again - this may be wrong on many levels, and kea is not intended to be used this way).

Integration into existing project

I just stumbled across this project. I really like what you're doing here, but I find myself wondering if I could integrate kea into my already existing react/redux/saga project. I expect I would have many components that would need access to kea-based infrastructure as well as the manually wired stuff I already have. Is there an elegant way to combine these two? I suppose I could wrap my kea-generated stuff with connect() from react-redux, but it would be nice to have a cleaner option.

If you have any suggestions, you might want to add it to the documentation.

HOC for functional components?

I didn't know where to best place this but I'd like to know if there are any plans to create this as an HOC for functional components and just passing all the state and actions down as props?

Thanks!

remote-redux-devtools

Looks like this library changed recently to use a new getStore method that wraps of a lot of the redux stuff together.

Is there a way to provide the compose function to getStore so that I can use the composeWithDevTools from remote-redux-devtools?

Looks like there is a fallback shown at the bottom of the getStore documentation, but using the new getStore abstraction would be nice.

"kea": "^0.25.1",

Who's using Kea?

Hey, just curious to know and to start collecting data for a future "projects" page: who's using Kea in the real world? :)

Please share:

  1. Company or product name + link to your website
  2. Logo
  3. What kind of project? How big is your team? How big is your codebase?
  4. Any other comments? :)
  5. Can I use this logo on the homepage... or you need to ask legal fist... or not at all?

[next.js] global plugins do not register before logic components

Hello there,

so, after quite a bit of debugging I noticed that including plugins directly works

// components/Users.js
...
import thunkPlugin from  "kea-thunk";
import { kea } from "kea";

export default  kea({
  plugins: [thunkPlugin],
  path: () => ["kea", "Users"],
  thunks: ({ actions }) =>  {
  ...
})(function Users(props)=>{...})

however registering plugins on the store level does not

// store.js
import thunkPlugin from 'kea-thunk'
import { getStore } from "kea";

export const createStore = preloadedState => getStore({ plugins: [thunkPlugin] })

upon inspection I noticed that the kea function is executed before the ActivatePlugins function is.

This happens even if I call the store before importing the component for some reason 🤔

// pages/index.js
import React, {Component} from 'react'
import { Provider } from 'react-redux'
import { createStore } from '../store'
let store = createStore()

import Users from '../components/Users'

export default class LandingPage extends Component {
  render() {
    return <Provider store={store}>
      <Users/>
    </Provider>
  }
}

And once the logic is initialized the global plugin is never referred to later
in this case all actions declared in thunks never show up.

so far I resolved this by simply directly including the plugin

any idea why?

my current proposed solutions are make global plugins run on already initialized logic
allways use plugins on the logic level (which I will do until a solution is presented)

in the mean time

I only figured out I can use plugins on the logic level by following by inspecting the code
would be nice if this is mentioned in the thunk plugin documentation
I realized later it's already mentioned in the kea function documentation but it's kinda not where I would have looked when faced with a problem related to a plugin

thank you for you time 😃

Better examples needed

Hey, currently there is only one example in the guide: TodoMVC

We need some more examples to showcase the functionality of kea, much like SoundRedux did for Redux.

Currently I can point to my own startup, a freelance project (and a few others) or to an alpha-stage open source data analytics platform when anyone asks for examples of projects that use kea in production. The last of the three has the source available, but is using an older version of kea.

Thus it would be great to have some fresh examples.

Is anyone up for the challenge of writing some?

Some ideas:

  • soundclound client (is it shutting down?)
  • github client
  • HN client
  • ... ?

Other ideas?

No PropTypes validation

I may be doing something wrong but I can't make the PropTypes validation works. If I have something like this:

import React from 'react'
import PropTypes from 'prop-types'
import { kea } from 'kea'

const counterLogic = kea({
  actions: () => ({
    increment: amount => ({ amount }),
    decrement: amount => ({ amount })
  }),

  reducers: ({ actions }) => ({
    counter: [0, PropTypes.number, {
      [actions.increment]: (state, payload) => state + payload.amount,
      [actions.decrement]: (state, payload) => state - payload.amount
    }]
  })
})

const Counter = ({
  actions: {
    increment, decrement
  },
  counter
}) =>
  <div>
    <div>{ counter }</div>
    <button onClick={() => increment(1)}>+</button>
    <button onClick={() => decrement(1)}>-</button>
  </div>

export default counterLogic(Counter)

It works fine. But if I change the increment calling to something like this:

    <button onClick={() => increment('abc')}>+</button>

It should raise an exception, right? Like it does with component proptypes validation.
But I'm not getting anything from console. If you run this component and try to increment something different from a number (like a 'abc' string), your component will receive '0abc' from counter prop. Maybe I'm doing something wrong or maybe it's a bug. I don't know, lol

Should we keep old Logic/Saga classes? Code refactor needed!

kea has been under development for more than a year by now. It started out with a completely different syntax to the recommended kea({}) approach, which is now well documented. The old ways are still available, but I want to remove them.

For example, what is now achieved with kea({}) was before achieved through Logic classes like so: https://gist.github.com/mariusandra/1b8eeb3f2f4e542188b915e27133c858

For sagas we had/have separate Saga classes that looked like this: https://gist.github.com/mariusandra/e6091b393e153c9edf3ba451a9d91aeb

There are also the old createLogic, createSaga, createKeaStore functions which are still exported and take up valuable bundle size.

In addition to all of that, I once implemented a way to have namespaced props, like so: keajs/kea-website@dcf107e

This is still usable for the old connect method (imported from kea/logic), but not anymore in the newer kea({}) syntax or the new connect alias. This approach was fun, but it screwed over propTypes and made the entire codebase more complex. I don't think anyone ever used them? To delete and simplify?

None of the above is tested.

All of this baggage is still there in kea v0.19. Should we hold on to this deprecated functionality going forward? What is the cost of removing them?

I'm writing this issue to address these points:

  1. have a trace of the changes to do
  2. explain to anyone peeking behind the hood why the current code is such a pile of spaghetti
  3. see the impact removing this functionality will have for the current users
  4. gauge if this is the right path to take, or if we should support these old ways going forward
  5. explain my intent of one day refactoring the codebase

@meikoudras @madisvain - as the two confirmed pre-0.19 kea users, do you have any opinion on these points?

My idea is to plant strong "deprecated" warnings for all of this in v0.20 and remove them by v0.22. I could keep the Saga classes around a bit longer, as the code for them is ridiculously simple

Why so large?

Kea provides a very concise way of collecting application logic, making it a really tempting framework to operate on, but why are its plugins so large?

screen shot 2017-10-25 at 19 48 09

In the previous image I included all packages even though I intend to only include thunk
but even still how can a mere wrapper have the same size as kea itself.

it makes some sense for kea being 21kb gzipped ; however the numbers I'm seeing suggests that kea could be suffering from maybe bad bundling, or at least the async plugins.

just wondering

Is it supporting thunk?

Hi, I love how kea abstract things. But is it supporting redux-thunk or not? Do you have sort of road map for supporting X in the future?

ReferenceError: regeneratorRuntime is not defined

Hi, I'm using create-react-app for my project and I followed the instructions listed in the documentation located here:

https://kea.js.org/guide/installation

The instructions I followed was Adding to apps made with create-redux-app.

After running through all of the following I npm start my application and I'm receiving the following errors.

ReferenceError: regeneratorRuntime is not defined

I figured this might just be an issue with the node_modules so I removed the entire node_modules folder and went ahead and re-installed all the packages using npm install since everything I installed the previous time had the --save flag, so essentially that would give me a clean copy of all my dependencies. Still receiving the same error.

Am I missing something??

This is what my package.json looks like:

{
  "name": "app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "bulma": "^0.5.1",
    "custom-react-scripts": "^0.1.4",
    "flow-bin": "^0.52.0",
    "font-awesome": "^4.7.0",
    "history": "^4.6.3",
    "husky": "^0.14.3",
    "kea": "^0.20.8",
    "lint-staged": "^4.0.2",
    "node-sass-chokidar": "0.0.3",
    "npm-run-all": "^4.0.2",
    "prettier": "^1.5.3",
    "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-redux": "^5.0.6",
    "react-router-dom": "^4.1.2",
    "react-router-redux": "^4.0.8",
    "redux": "^3.7.2",
    "redux-saga": "^0.15.6",
    "reselect": "^3.0.1"
  },
  "lint-staged": {
    "src/**/*.{js,jsx,json,css}": [
      "prettier --single-quote --write",
      "git add"
    ]
  },
  "scripts": {
    "start-js": "react-scripts start",
    "start": "npm-run-all -p watch-css start-js",
    "build": "npm run build-css && react-scripts build",
    "flow": "flow",
    "precommit": "lint-staged",
    "build-css": "node-sass-chokidar src/ -o src/",
    "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  },
  "devDependencies": {
    "@storybook/react": "^3.2.3"
  }
}

loading plugin (was: Use worker to fetch data on click?)

At the moment I'm trying out Kea in a new project but I'm still confused about a couple of things. Maybe it is because I'm not that well-versed in Redux/Redux saga. I've got an application where I simply want to send some data json I fetched as a property. The action is called setCurrentArticle.
I've placed the actual fetch call in a worker function called fetchArticleData. Now it does fetch the data, but it keeps on looping after that. Am I missing something fundamental here?

    takeLatest: ({ actions, workers }) => ({
        [actions.setCurrentArticle]: workers.fetchArticleData,
    }),

    workers: {
        * fetchArticleData(action) {
            const { setCurrentArticle } = this.actions;
            const id = action.payload.currentArticle.id;
            const url = `${apiEndpoints.root}stories-api/${id}`;
            const response = yield call(fetch, url);
            if (response.status === 200) {
                    const json = yield response.json();
                    yield put(setCurrentArticle(json));
            }
        },
    },

regeneratorRuntime is not defined

Why I have regeneratorRuntime is not defined error? I've installed regenerator-runtime and still nothing changes.

Note: I use create-react-app

Unit Testing

Hi
Whats the proper setup to unit test the reducers and selectors defined in kea? do we use connect to import them in our tests?
Thanks!

kea combined with react-redux `connect` --> no kea sagas run

I found this while trying out kea in an existing app. I have a HOC that uses connect from react-redux. Long story short, you can't call kea({...options})(MyComponent) if MyComponent has already had connect (from react-redux) called on it.

If you do this and call the actions defined in your kea options, the actions will fire but the corresponding sagas will not run.

More (too much?) detail:

export default function HOC(callback, mapStateToProps, mapDispatchToProps) {
  return function factory(WrappedComponent) {
    class Wrapper extends PureComponent {
      componentDidMount() {
        callback(this.props);
      }
      render() {
        return <WrappedComponent {...this.props} />
      }
    }

    return connect(mapStateToProps, mapDispatchToProps)(Wrapper);
  }
}

// in another file...
const Logic = kea({
    actions: () => ({
        greet: person => ({person}),
    }),
    workers: {
        handleGreeting: function* (action) {
            yield call(hello, action.payload.person);
            // etc...
        },
    },
    takeEvery: ({actions, workers}) => ({
      [actions.greet]: workers.handleGreeting,
    }),
});

const SillyComponent = props => (<div>Sent a greeting to {props.person}</div>);
// dispatch api call on mount...
const callback = (props) => props.actions.hello(props.person);

export default Logic(HOC(callback)(SillyComponent))

If you use <SillyComponent person="Bob"/> somewhere, it will dispatch the action when it mounts, but workers.handleGreeting will never run.

Sagas not running

Given a simple kea logic definition applied to a component:

const ImportQuoteLogic = kea({
 actions: () => ({
    selectFile: (fileObj: File) => ({fileObj}),
    cancelImport: () => ({}),
  }),

  reducers: ({actions}) => ({
    quoteImport: [{}, PropTypes.object, {
      [actions.selectFile]: (state, {fileObj}) => ({filename: fileObj.name}),
      [actions.cancelImport]: state => ({}),
    }],
  }),

  workers: {
    handleFile: function* (action) {
      console.log('process file');
      yield call(console.log, 'process file', action.payload);
    },
  },

  start: function* () {
    console.log('start');
    yield call(console.log, 'start');
  },

  takeEvery: ({actions, workers}) => {
    console.log('returning action to worker mapping...');
    return ({
      [actions.selectFile]: workers.handleFile,
    });
  },
});

The sagas don't run. start never prints to the console; neither does 'returning action to worker mapping'. The actions and reducers all work (as observed in the redux dev tools); just the sagas are ignored.

I have a few other kea-fied components that are behaving just fine, so it is not my overall kea setup. I feel like it must be just staring me in the face, but I've been at this for hours now and I'm getting nowhere.

Apollo & Stateless Components

Hi,
I'm really liking KeaJS and the abstractions that it brings to our code.

However I would appreciate it if you could provide examples on how to integrate Apollo & GraphQL (perhaps use Graph.cool service for the backend) with Kea JS. How do we go about using HOC from apollo library within sagas inside Kea?

Also I'm wondering if Kea would play nice with stateless functional components (so that I can use recompose helper utils instead of using the Kea decorator syntax)?

(I'm still new to Redux/Sagas etc so please bear with me)

Thanks!

Add UMD build

UMD build will be very convenient, e.g. if I want to try out the library on codepen.

Uncaught TypeError: Cannot read property 'inline-0' of undefined

I am running into this error on v0.20.5 when trying to use the connect functionality, following the example in the docs.

Uncaught TypeError: Cannot read property 'inline-0' of undefined

Importing a logic from a separate file and applying it in its entirety to a component works fine. However, trying to connect specific actions or props to a component fails. I've tried connecting using a decorator, with the shorthand syntax (connect(options)), and with the long syntax (kea({ connect: { ... } }), but i get the same error in all cases.

I am able to reproduce this in a simple Gist. Is there a step that i'm missing to make connect() work or is this a bug in kea? I noticed that there has been some recent development activity, so maybe the docs are just outdated.

Please let me know if there is anything you need me to clarify about what is happening.
Thanks!

Edit: Here's the full stack trace.

selectors.js:6 Uncaught TypeError: Cannot read property 'inline-0' of undefined
    at concat.reduce (selectors.js:6)
    at Array.reduce (<anonymous>)
    at pathSelector (selectors.js:6)
    at rootSelector (selectors.js:22)
    at index.js:86
    at Object.reducer1 (index.js:36)
    at Object.keys.forEach.propKey (kea.js:317)
    at Array.forEach (<anonymous>)
    at kea.js:316
    at Object.runComponentSelector [as run] (connectAdvanced.js:26)
    at Connect.initSelector (connectAdvanced.js:178)
    at new Connect (connectAdvanced.js:119)
    at ReactCompositeComponent.js:294
    at measureLifeCyclePerf (ReactCompositeComponent.js:75)
    at ReactCompositeComponentWrapper._constructComponentWithoutOwner (ReactCompositeComponent.js:293)
    at ReactCompositeComponentWrapper._constructComponent (ReactCompositeComponent.js:279)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:187)
    at Object.mountComponent (ReactReconciler.js:45)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:370)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:257)
    at Object.mountComponent (ReactReconciler.js:45)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:370)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:257)
    at Object.mountComponent (ReactReconciler.js:45)
    at mountComponentIntoNode (ReactMount.js:104)
    at ReactReconcileTransaction.perform (Transaction.js:143)
    at batchedMountComponentIntoNode (ReactMount.js:126)
    at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:143)
    at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
    at Object.batchedUpdates (ReactUpdates.js:97)
    at Object._renderNewRootComponent (ReactMount.js:319)
    at Object._renderSubtreeIntoContainer (ReactMount.js:401)
    at Object.render (ReactMount.js:422)
    at Object../src/index.js (index.js:79)
    at __webpack_require__ (bootstrap 7abea5da1d167805669e:659)
    at fn (bootstrap 7abea5da1d167805669e:85)
    at Object.0 (index.js:80)
    at __webpack_require__ (bootstrap 7abea5da1d167805669e:659)
    at ./node_modules/ansi-regex/index.js.module.exports (bootstrap 7abea5da1d167805669e:708)
    at bundle.js:712

Can I not use propTypes?

Types can be enforced by a type system like Flow or TypeScript, and there's no real benefit (that I am aware of) to be gained in production from including them.

can they be made optional? that way they can be stripped using a babel codemode for example when building for production.

Redesign the homepage

Hey, I think this part of the kea.js.org website needs to be upgraded:

screen shot 2017-09-29 at 21 57 23

The first thing I'd do is rework the bottom part into something like what inferno and other similar sites have:

screen shot 2017-09-29 at 22 01 45

Anyone up for the task? :)

If you want to play with the website, just clone it, yarn, yarn start and http://localhost:2000

Kea with Preact?

Hey folks,

I've just trying to differentiate Kea with some other frameworks/libraries using Redux as a base but could not find any source using preact as its view layer integrated with Preact. Is there any plan to do such an example and step-by-step guide using Kea with Preact?

Update: I have tried with a sample app and got he following:

ERROR in ./~/kea/lib/kea/index.js
Module not found: Error: Can't resolve 'react-redux' in '/<repo-path>/node_modules/kea/lib/kea'
 @ ./~/kea/lib/kea/index.js 52:18-40
 @ ./~/kea/lib/index.js
 @ ./src/containers/some-container.js
 @ ./src/components/app.js
 @ ./src/index.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src

Note: I am using preact-redux.

Cheers

Baris

Connect and non singletons (logic with key)

Hi Marius,
First, Thanks a lot for keajs.
I am trying to use connect along with key.
I ran into an issue??
It is most likely not an issue, may be I just do not know how to use it.

  • Importing props from another logic using props works when the logic is a singleton
  • Importing props from another logic using props does not work when the logic is not a singleton (uses a key).

Example 1: props works inside connect

// with-visible.js
export default kea({
  path: () => ['scenes', 'App', 'Alert'],  
  actions: () => ({
    show: (args) => ({ ...args, type: 'show' }),
    hide: (args) => ({ ...args, type: 'hide' }),
  }),
  reducers: ({ actions, key }) => ({
    visible: [true, PropTypes.bool, {
      [actions.show]: () => true,
      [actions.hide]: () => false,
    }]
  })
});
import withVisible from './with-visible';

const options = {
  actions: [
    withVisible, [
      'show',
      'hide'
    ]
  ],
  props: [
    withVisible, [
      'visible',
    ],
  ],
};

Example 2: props does not work inside connect

export default kea({
  key: ({id}) => id,
  path: (key) => ['scenes', 'App', 'Alert', key],  
  actions: () => ({
    show: (args) => ({ ...args, type: 'show' }),
    hide: (args) => ({ ...args, type: 'hide' }),
  }),
  reducers: ({ actions, key }) => ({
    visible: [true, PropTypes.bool, {
      [actions.show]: (state, payload) => payload.key === key ? true : state,
      [actions.hide]: (state, payload) => payload.key === key ? false : state,
    }]
  })
});
import withVisible from './with-visible';

const options = {
  actions: [
    withVisible, [
      'show',
      'hide'
    ]
  ],
  props: [
    /*
    // This does not work because withVisible is not a singleton (has a key)
    withVisible, [
      'visible',
    ],
    */
    (state) => {
      return state.scenes.App && 
        state.scenes.App.Alert && 
        state.scenes.App.Alert.Alert1 && 
        state.scenes.App.Alert.Alert2 ? state.scenes.App.Alert: {
        Alert1: { visible: true },
        Alert2: { visible: true }
      }
    }, [
      'Alert1',
      'Alert2'
    ]
  ],
};

What is the idiomatic way of doing example 2 using connect when logic is not a singleton (has a key)?

You can see the complete source here:
https://github.com/codingarchitect/component-state-kea/blob/master/src/with-visible.js#L5
https://github.com/codingarchitect/component-state-kea/blob/master/src/App.jsx#L13-L32

Thanks,

Unit test console error

I'm having this error on my console

console.error node_modules/kea/lib/scene/store.js:278
    [KEA-LOGIC] Path starting with "components" is not connected to the reducer tree! Make sure to call keaReducer() before any calls to kea() take place! [ 'components', 'auth', 'index' ]

I've tried following your tests by doing this

import {keaReducer} from 'kea';
const scenesReducer = keaReducer('components');
let reducerState1;
beforeEach(() => {
  reducerState1 = scenesReducer({}, { type: 'discard' });
});
it('should connect to reducer tree', () => {
  expect(reducerState1).toEqual({});
});

how can I fix it?

Another issue is testing using constants

Logic:

export default kea({
  path: () => ['components', 'auth', 'index'],
  constants: () => [ 'LOGIN_REQUEST'],
  actions: ({constants}) => ({
    requestLogin: creds => ({
      type: constants.LOGIN_REQUEST,
      creds
    })
  })
})

Test:

  it('should create an action to request login', () => {
        const credentials = {
            username: '[email protected]',
            password: 'test123'
        };

        const expectedAction = {
            type: constants.LOGIN_REQUEST,
            payload: {
                creds: credentials
            } 
        };

        expect(actions.requestLogin(credentials)).toEqual(expectedAction);
    });

Console error:

Difference:
    
    - Expected
    + Received
    
    @@ -2,8 +2,9 @@
       "payload": Object {
         "creds": Object {
           "password": "test123",
           "username": "[email protected]",
         },
    +    "type": "LOGIN_REQUEST",
       },
    -  "type": "LOGIN_REQUEST",
    +  "type": "request login (components.auth.index)",
     }

So the constant is inside the payload and the action type follow the action name.
So I was wondering why it can't match the constant in this case?

Thank for your support

Hot reloading => Already created action xxx

When I use hot reloading for react, whenever it fires, koa will throw this error [KEA-LOGIC] Already created action "set group (app.materials)" for each action. Also, the actions will not work from then on, only on a hard reload F5 of the website it'll work again.

I wonder if you could change the behaviour of kea to overwrite actions so this works, or do you have another idea how to resolve this?

Why do we want to use kea? And when?

I find the README is lacking this key concept explanation. So raise this issue here.
I'm currently using a solution of redux + thunk + redux-promise-middleware,
why do I want to use kea and when?

`createKeaStore` was not found in '../scene/store'

Hi,

I tried to install kea and configure it like described in step 1 https://kea.js.org/guide/installation but i'm getting error:

./node_modules/kea/src/logic/_deprecated.js
91:9-12 "export 'createKeaStore' (imported as 'cks') was not found in '../scene/store'

This happened using version 0.19.12.
I'm using module main field https://github.com/keajs/kea/blob/master/package.json#L8 via webpack + babel

Error is coming from https://github.com/keajs/kea/blob/master/src/logic/_deprecated.js#L3
and export is actually missing in https://github.com/keajs/kea/blob/master/src/scene/store.js
But https://github.com/keajs/kea/blob/master/src/scene/index.js#L6 is also trying to export

So it looks like createKeaStore is missing in ./src/scene/store.js`

Router (ReactRouter V4) nested inside a kea connected component does not work

Connecting Kea to a component that contains routes does not work properly, the routes are not matched.

import React,  { Component } from 'react'
import { kea } from 'kea'

const logic = kea({})

class _Wrapper extends Component {
  render() {
    return(
      <div>{this.props.children}</div>
    )
  }
}

const Wrapper =  logic(_Wrapper) // switch routes does not work
//const Wrapper = _Wrapper  // switch routes works

const App = () => (
  <ConnectedRouter history={history}>
    <Wrapper>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/foo">Foo</Link></li>
        <li><Link to="/bar">Bar</Link></li>        
      </ul>
      <Route exact path="/" component={Home} />
      <Route path="/foo" component={Foo} />
      <Route path="/bar" component={Bar} />
    </Wrapper>    
  </ConnectedRouter>
)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.