Giter VIP home page Giter VIP logo

Comments (7)

quisido avatar quisido commented on May 18, 2024

Is my interpretation of this request accurate?

You have two reducer functions, reducer1 and reducer2. When reducer1 executes, you want it to be followed by reducer2?

Component calls this.dispatch.reducer1, but both reducer1 and reducer2 execute and update the state?

from reactn.

cocodrino avatar cocodrino commented on May 18, 2024

Hi @CharlesStover it's not exactly like that, instead of two reducer I'd have one reducer with two actions...like the example

function reducer(state, action) {
  switch (action.type) {
    case "fetch-start":
      fetch('wwww.example.com')
        .then(r => r.json())
        .then(r => action.asyncDispatch({ type: "fetch-response", value: r }))
      return state;

    case "fetch-response":
      return Object.assign({}, state, { whatever: action.value });;
  }
}

after end fetch-start must call fetch-response....

similar to what you can achieve with redux thunks, now...if there is a better way to achieve this please let me know...

thank you.

from reactn.

quisido avatar quisido commented on May 18, 2024

The example provided is a bit odd in that fetch-start doesn't update the global state. If you only want to update the global state once, ReactN supports Promises out of the box.

Would something like this be what you are wanting to achieve?

function reducer(state, action) {
  return fetch('wwww.example.com')
    .then(r => r.json())
    .then(r => ({
      whatever: r,
    });
}

Based on my interpretation of the code, correct me if I'm wrong, you are fetching some API, parsing the response, and setting the whatever global property to the response. The snippet I provided does this -- if your reducer returns a Promise, the resolved (or rejected!) value of that Promise will merge into the global state.

I think Sagas typically update the state multiple times -- such as fetch-start setting loading: true followed by fetch-response setting loading: false -- which is a feature that can be done currently, but not with an intuitive interface. I am all for a better Saga interface, such as using generators, but I want to make sure I thoroughly address all possible use cases and side effects of generators and sagas before implementing it, as I am not particularly familiar with Sagas.

If you want to a single reducer to update the global state multiple times currently, you would need to use the setGlobal helper:

import { setGlobal } from 'reactn';
function reducer(state, action) {
  return setGlobal({ loading: true })
    .then(() => {
      return fetch('www.example.com')
        .then(r => r.json());
    })
    .then(r => ({
      loading: false,
      whatever: r,
    });
}

In the above, this reducer sets the state loading to true, then fetches and finally sets loading to false and whatever to the response.

I am not happy with this interface, but it works and will always work. I am looking into learning Sagas more in-depth now to try to get something better, like generators, to handle this use case more intuitively.

Let me know if you have more feedback to drive the development of this process, e.g. what you would like to write, your use cases that can't be handled by the current implementation, etc.

Thank you. :)

from reactn.

cocodrino avatar cocodrino commented on May 18, 2024

thanks for the reply, my question arises as i am running some tests and testing the lib, then i found this situation

I have 2 actions, one registers the user and the other logs in, both actions call an endpoint on my server

now, if I want that when the user registers automatically login to the server (obviously if the registration was correct)...currently I would have to duplicate the code, because I would have to call back to the endpoint where I login...with thunks I could call the registry action and if this works I would call login

easy-peasy also has thunks, you can see the example
https://github.com/ctrlplusb/easy-peasy#thunkaction

or the example inside
Example dispatching an action from another part of the model

here you can see than my thunk can dispatch several actions sequentially, for instance,
save the task in the server, when it's saved then add to my local tasks and then dispatch some action for remove the load spinner

you could achieve this using promises right now but you'd need duplicate many code, instead of create some actions and when you need it just dispatch the action....hopefully my idea will be a bit more clear now

thank you

from reactn.

quisido avatar quisido commented on May 18, 2024

It seems like a solution would be for the reducers to be accessible inside each other.

// Concatenate a task to the global tasks array.
function addTodo(state, _dispatch, task) {
  return ({
    tasks: state.tasks.concat([ task ]),
  });
}

// Save a task on the server, then add it to the global tasks array.
function saveTodo(state, dispatch, task) {
  return ajax.post('/todo/task', task)
    .then(() => {
      dispatch.addTodo(task);
    })

    // If an error occurred, update the error property to contain the error.
    .catch(err => ({
      error: err,
    });
}

// Tasks starts empty.
// tasks: []

// Add to the global tasks array
dispatch.addTodo('make an app');
// tasks: [ 'make an app' ]

// Save a task to the server, then also add it to the global tasks array if successful.
dispatch.saveTodo('save this todo to the server')
// tasks: [ 'make an app', 'save this todo to the server' ]

Would the above make sense?

// initial
setGlobal({
  bool: false,
  num: 0,
  str: 'abc',
});

// toggle boolean
addReducer('toggle', state => ({
  bool: !state.bool,
});

// add a number
addReducer('add', (state, dispatch, num) => ({
  num: state.num + num,
});

// append a string
addReducer('append', (state, dispatch, str) => ({
  str: state.str + str,
});

// saga
addReducer('mySaga', (state, dispatch, num, str) => {
  dispatch.toggle();
  dispatch.add(num);
  setTimeout(() => {
    dispatch.append(str);
  }, 1000);
});

dispatch.mySaga(5, 'xyz');
/*
-- immediately:
bool: true
num: 5
str: 'abc'
*/

dispatch.mySaga(10, '123');
/*
-- immediately:
bool: false
num: 15
str: 'abc'

-- after 1 second:
-- append xyz and 123 dispatch asynchronously
bool: false
num: 15
str: 'abcxyz123'
*/

The only thing I immediately don't like about this syntax is how reducers now have both (state, dispatch, ...params) state and dispatch before the params. It feels less intuitive than (state, param), since most reducers won't be sagas.

If the above implementation solves your use case, let me know. It's a huge step towards implementing sagas. It's just a matter of finding a syntax that is intuitive. I think the above is intuitive for sagas, but not necessarily for non-saga reducers.

from reactn.

cocodrino avatar cocodrino commented on May 18, 2024

mmm yes it seems to be a real good solution, I'd test it...thank you!!!

from reactn.

quisido avatar quisido commented on May 18, 2024

Thank you for the feedback. I'll let this rattle around a bit before I implement it in 2.0, see if I can get some more feedback.

from reactn.

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.