Giter VIP home page Giter VIP logo

Comments (6)

redonkulus avatar redonkulus commented on May 25, 2024

@pablopalacios you want to take a look at this?

from fluxible.

pablopalacios avatar pablopalacios commented on May 25, 2024

@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:

  1. read data from the store when you don't need to subscribe to it (eg. server data that is never updated in the browser)
  2. 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.

billyrrr avatar billyrrr commented on May 25, 2024

@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:

  1. 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.

  1. Include in document a warning to state that getStateFromStore must be immutable and not to be updated on props change.
  2. 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.

pablopalacios avatar pablopalacios commented on May 25, 2024

@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.

billyrrr avatar billyrrr commented on May 25, 2024

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.

pablopalacios avatar pablopalacios commented on May 25, 2024

@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)

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.