Comments (7)
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.
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.
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.
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.
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.
mmm yes it seems to be a real good solution, I'd test it...thank you!!!
from reactn.
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)
- Can we drop in preact in place of React while using Reactn? HOT 1
- Global state resets after Route change HOT 5
- Don't export functions with the same name as common React hooks HOT 1
- [Query] Does updating a global nested state, require deep copy ? HOT 2
- why is useEffect exported from the package? HOT 2
- Dependabot can't resolve your JavaScript dependency files
- Provider.useDispatch Errors with TypeScript HOT 1
- Global reducers do not work in TypeScript 4. HOT 4
- Ability to update state with a function with globalPropertySetter HOT 1
- React Native expo HOT 2
- react native compatible? HOT 5
- Feature request: add previous global state to addCallback parameters HOT 10
- useEffect in useGlobal has no dependencies and will run every render HOT 1
- Document how to put arrays and etc. in global state HOT 6
- Unwanted batch rendering
- Argument of type 'string' is not assignable to parameter of type 'never' HOT 3
- Dispatch re-renders components even when state is unchanged. HOT 2
- Set `peerDependencies` to `"@types/react": "^16.8.0 | ^17.0.2"` HOT 2
- Issue resolving dependency to `use-force-update` in react-native/expo project HOT 7
- Dependency Use force update 1.0.10 causes a Type Error HOT 7
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 reactn.