Comments (6)
@pablopalacios you want to take a look at this?
from fluxible.
@billyrrr yeah, I completely understand what you are saying. Currently useFluxible
is just a primitive hook that doesn't do much more than using the useContext
to fetch fluxible context and provide it to the user/component.
There are only 2 use cases for it:
- read data from the store when you don't need to subscribe to it (eg. server data that is never updated in the browser)
- call
executeAction
Creating the useStore
is the natural next step. This section explain more or less how the flow should be: https://fluxible.io/api/components.html#accessing-stores. But the difference between this section and the real connecToStores
is that the later also take the props in consideration to retrieve data from the store.
So, let's say, creating a very simple useStore
that doesn't take component props in consideration should be simple:
function useStore(storeName, getStateFromStore) {
const { getStore } = useFluxible().
const store = getStore(storeName);
const [state, setState] = useState(getStateFromStore(store));
function updateState() {
setState(getStateFromStore(store));
}
useEffect(() => {
store.on('change', updateState);
return () => store.removeListener('change', updateState);
}, [store]);
return state
}
Notes:
- We need the
getStateFromStore
because, unfortunately, there is no interface for how to retrieve the store state; - I'm not so sure about the
removeListener
part (if it will work or not), but the point is, we also must unsubscribe from the store; - I'm also not sure about the
useEffect
dependencies here;
However, as soon as we add props
in the game (let's say, to retrieve a todo item from the store given a todo id from the props), then things got a little bit more complicated. We also need to add the props in the useEffect
dependency list. Then I would recommend you to read the issues that react-redux
faced (https://react-redux.js.org/api/hooks#usage-warnings and https://kaihao.dev/posts/Stale-props-and-zombie-children-in-Redux).
But anyway, perhaps we could just start small and have no props support... @redonkulus what do you think?
@billyrrr if you can provide a PR I will gladly support you with reviews ;)
from fluxible.
@pablopalacios Thank you for the detailed advice. I will start with the implementation of props-free useStore
. Though, it seems that the user can specify the todo id by binding the id to the getStateFromStore
function. For example:
function TodoItem({ todoId }) {
const getStateFromStore = store => {
return store.getTodoById(todoId);
}
const todo = useStore(TodoStore, getStateFromStore);
return ...
}
If props-free useStore
is to be released for production, I want to see if the following options could remedy this:
- pass the entire store as the return of the hook. (This may not work)
function TodoItem({ todoId }) {
const store = useStore(TodoStore);
const todo = store.getTodoById(todoId);
return ...
}
@pablopalacios has mentioned that:
We need the getStateFromStore because, unfortunately, there is no interface for how to retrieve the store state;
Is the lack of interface due to consistency issues? For example, getStateFromStore
needs to invoked by fluxible rather than the user to avoid "user calling getStateFromStore on a weak reference". In which case, I would see why this can be a dead-end.
- Include in document a warning to state that getStateFromStore must be immutable and not to be updated on props change.
- Not releasing the prop-free hook for production.
I will continue with a PR based on your useStore
draft, and at the same time we can keep the discussion going.
Thanks!
from fluxible.
@billyrrr regarding using props inside getStateFromStore
, I'm pretty sure that it will not work (with the implementation that I proposed), since getStateFromStore
will not be called when the props changes (only the function definition will be changed). But you can add a test case for it in your PR.
Regarding the lacking of interface, I mean, it would be cool if useStore
could work like this:
const state = useStore('StoreName');
But since fluxible stores have no strict interface about how to retrieve their state, (eg. RouterStore
has a bunch of getter methods that are specific to RouterStore
while stores created with createReducerStore
will have a getState
method). Because of that, users must be responsible for retrieving the data:
const getStateFromStore = store => {
return store.getState()
}
const Component = () => {
const state = useStore(Store, getStateFromStore);
// ...
}
from fluxible.
I realized that there were some issues with a solution I proposed earlier. (most due to shallow prop comparison, and will not work) (It has since been deleted. Will post an amended version soon. Please ignore commit e415fe7 which will be rolled back soon)
from fluxible.
@billyrrr I've created an example to demonstrate the stale props with the current connectToStores
function. Since it's already an issue there, I think there are no blockers to already start using props with the useStore
that you are doing.
from fluxible.
Related Issues (20)
- Support registering services that return promises HOT 4
- Some properties are not showing. HOT 1
- compatibility with React v16 HOT 4
- An in-range update of babel-eslint is breaking the build 🚨 HOT 3
- An in-range update of sinon is breaking the build 🚨 HOT 5
- [addons-react] Following React 16.3+ new Context API ? HOT 7
- componentWillReceiveProps to getDerivedStateFromProps HOT 5
- Version 10 of node.js has been released HOT 1
- [fluxible] context.executeAction(action, null, callback) invokes the callback before the async action finishes HOT 1
- An in-range update of react is breaking the build 🚨 HOT 2
- An in-range update of react is breaking the build 🚨 HOT 25
- Should dispatch NAVIGATE_FAILURE if action is not able to resolve HOT 2
- An in-range update of eslint-plugin-react is breaking the build 🚨 HOT 12
- Update React lifecycle methods HOT 2
- [fluxible-addons-react] react 16 task list HOT 26
- TypeError: this.props.currentRoute is null HOT 2
- Render a component when error occurs HOT 1
- Question regarding debug dependency HOT 6
- Update Access the context site docs
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 fluxible.