Comments (6)
In the hybrids, you don't need a state
or props
thing. All your properties are available in other properties (when set as a getter, including render method). The hybrids descriptors object is a flat key -> value map. If you want to connect more data from a redux store, you should call connect
for each of them:
const Component = {
myReducer: connect(store, state => state.myReducer), // it should be 'state' not 'store' as you wrote
myOtherThing: connect(store, state => state.myOtherThing),
// usage of the data from redux store
mergedThings: ({ myReducer, myOtherThing }) => myReducer + myOtherThing,
}
The main concept of the library is to have independent properties, each of them are defined separately and can be a redux store value, simple property mapped from an attribute or something more complex as a children
or parent
factory.
However, if you really want a props
property, you can do something like this:
const Component = {
props: connect(store, ({ myReducer, myOtherThing } ) => ({ myReducer, myOtherThing })),
mergedThings: ({ props }) => props.myReducer + props.myOtherThing,
}
The above example uses destructuring (takes two properties from store state) and returns object with this two props.
from hybrids.
Oh okay, i just wanted to know if it was intended or maybe something that passed through. I wanted to make something like react-redux binding, something that I could say to the component what reducers I need and put only these.
The workaround was to put getState() directly on the props, it worked, but the props now has more than the component need. Well, at least it's working, I can keep up with the rest of my stuff while I think in a more descent way. Maybe make this mergedThings stuff inside of the redux binding I've made for hybrids.
from hybrids.
I supposed, that you have used connect
factory function from an example with a redux counter. If you would use this:
// This is a factory for connecting redux store.
// It can be taken out from here and use in other elements.
const connect = (store, mapState) => ({
get: mapState ? () => mapState(store.getState()) : () => store.getState(),
connect: (host, key, invalidate) => store.subscribe(invalidate),
});
It is very flexible what you return in the function from the second argument(mapState
). It works pretty the same as it works in react-redux
. It can map whole current state
of the redux store into anything you need - an object with props, simple value, or something calculated from state.
I still don't understand what you mean by the reducers. Reducer is a function which creates a new state of the store by dispatching an action, it is not a data that you want to connect to the component.
from hybrids.
What I wanted was the possibility of having inner properties inside my "props", this way, my actions and states would be inside it, just like redux do.
export const connectComponent = (
reduxStore,
reduxStoreDictionary = {},
actionsDictionary = {},
component,
) => {
let componentWithProps = { ...component, props: connect(reduxStore) };
Object.keys(actionsDictionary).forEach((actionPropertyName) => {
componentWithProps = {
...componentWithProps,
actions: {
...componentWithProps.actions,
[actionPropertyName]: actionsDictionary[actionPropertyName],
},
};
});
return componentWithProps;
};
As you can see, I'm using connect method to put the whole app state inside the props, but if I have 5 different reducers and the component only needs 2, it will get everything.
I tried something like this:
- let componentWithProps = { ...component, props: connect(reduxStore) };
+ let componentWithProps = component;
+ Object.keys(reduxStoreDictionary).forEach((reducerPropertyName) => {
+ componentWithProps = {
+ ...componentWithProps,
+ props: {
+ ...componentWithProps.props,
+ [reduxStoreDictionary[reducerPropertyName]]: connect(reduxStore, state => state[reducerPropertyName]),
+ },
+ };
+ });
This way, I would get only the needed state for the component, but this don't work.
from hybrids.
It won't work because the component definition is a flat key -> descriptor map. The library goes to your props
or actions
and checks if this object has get
or set
method at least to interpret it as a property definition. Otherwise it uses translation, and in this case, it will wrap your object (with actions or props) with property
factory.
You can not create nested properties inside of the object value. It is not supported and I think not really useful. How you can deal with it? Let's go with your two problems separately.
The props problem. I think this can be handled by my proposal in my first comment. You can map your redux state in any way to create getter property (which will be updated any time when the state changes):
{
props: connect(reduxStore, (state) => {
// your manipulation code
return { one: state.one, two: state.two + state.three };
}),
render: ({ props }) => html`
<div>${props.one} ${props.two}</div>
`,
}
The actions problem. In your last code example, you are passing actions from actionDictionary
, so I don't know if the are just action creators and the return plain object with action type and payload, or the are already bind to the store instance. Regardless of what you pass, I think you don't need it at all. It would be much clearer if you use your actions directly in the component definition, like this:
import myStore, { connect } from './myReduxStore';
import { someAction } from './reduxActions';
export default {
props: connect(myStore, (state) => {...}),
render: ({ props: { param1, param2 } }) => html`
<my-element oncustomevent="${() => myStore.dispatch(someAction(param1, param2))">
....
</my-element>
`,
}
The main concept of the library is to have clear data sources in properties, and external functions for all side effects, which are connected to the component by the events in render method or connect or other places of the properties definition.
If () => myStore.dispatch(someAction)
is too verbose for you, you can also create little helper over your store instance and export it form file where you setup store:
// myReduxStore.js
import createStore from 'redux';
...
const reduxStore = ....;
export default reduxStore;
export const dispatch = (action) => () => reduxStore.dispatch(action);
// myComponent.js
import { dispatch } from './myReduxStore';
import { someAction } from './reduxActions';
{
render: ({ props: { param1, param2 } }) => html`
<my-element oncustomevent="${() => dispatch(someAction(param1, param2))}">
...
`,
}
At last but not least, if you want to make this action your public API of the component, you can also use that function in property getter, and call that property in render method:
{
// Here is a function chain, because the first function is a getter, so it is called when you want
// a property value, and that property should return agian a function, which will be called
// when event of <my-element> occur.
someAction: ({ props: { param1, param2 } }) => () => dispatch(someAction(param1, param2)),
render: ({ someAction }) => html`
<my-element oncustomevent="${someAction}">
...
`,
}
All the above examples assume, that parameters to your action creator are taken from the component properties (it can be your props, but also any other defined properties).
EDIT:
If you really want to have all your actions available as a actions
property, it also possible:
import { connect } from './connect';
export function connectComponent(store, actionsDictionary = {}, component) {
return {
...component,
props: connect(store),
actions: () => Object.keys(actionsDictionary).reduce((acc, key) => ({
...acc,
[key]: (...args) => store.dispatch(actionsDictionary[key](...args)),
}, {}),
};
}
Using this pattern, you have props
with the redux state, and actions
as an object with keys as a bind action, which dispatches to the connected redux store.
from hybrids.
I'm closing now. If you would have other issues with connecting to redux feel free to reopen.
from hybrids.
Related Issues (20)
- Add support for "TypeScript v5" HOT 3
- I can't create an arbitrary number of nested forms: HOT 6
- Small Type Inferencing Issue with Property<E, V> HOT 6
- Cannot pass an object to the API via the "list" method HOT 7
- version 8.2.17 backwards compatibility is broken! HOT 9
- Expand the functionality of drafts
- sync() with nested models is broken HOT 4
- Allow storing an object in a component property HOT 4
- Add partial loading of model data HOT 3
- Why do you remove the lastValue? HOT 2
- The store logs a lot of errors HOT 4
- Convert a Whole Component to Web Component HOT 8
- Scoped CSS HOT 6
- lagging update glitch HOT 2
- Component properties cannot be setted until they are observed HOT 2
- `store.set()` is very slow HOT 5
- Store loads items data when iterating the list of items HOT 2
- store.record(store.record('')) bug HOT 3
- Protect Models from incorrect use HOT 9
- Passing a transform function to 'reflect:' in a property descriptor has no effect without also specifying an observer HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hybrids.