admin管理员组文章数量:1296873
I have an empty state
object that is instantiated with default empty fields on app start.
It contains an empty array named users
.
const state = {
users: []
}
On start I send some mands to server and server then sends data in response.
As I need to populate users
, I think I just want to replace the whole users array with a new one that is received from server.
I read that in redux you take the current state, apply some changes to it and return a new state. It sounds good when I want to, say, change user password, then I would call an action like this:
{
action: 'CHANGE_PASSWORD',
user: 'john',
password: 'karamba',
}
It would be managed by the dispatcher, where a user john
would be found in the current state and the password would be replaced with the new one.
But is this correct for the scenario where I want to load some initial data?
If so, how would an action look like?
{
action: 'FETCH_USERS'
}
And then the reducer would replace the whole users
array?
I have an empty state
object that is instantiated with default empty fields on app start.
It contains an empty array named users
.
const state = {
users: []
}
On start I send some mands to server and server then sends data in response.
As I need to populate users
, I think I just want to replace the whole users array with a new one that is received from server.
I read that in redux you take the current state, apply some changes to it and return a new state. It sounds good when I want to, say, change user password, then I would call an action like this:
{
action: 'CHANGE_PASSWORD',
user: 'john',
password: 'karamba',
}
It would be managed by the dispatcher, where a user john
would be found in the current state and the password would be replaced with the new one.
But is this correct for the scenario where I want to load some initial data?
If so, how would an action look like?
{
action: 'FETCH_USERS'
}
And then the reducer would replace the whole users
array?
3 Answers
Reset to default 6Let just cover some basics first
- All state changes within a app are stored in a single object state tree.
- This state tree needs to be immutable.
- Anytime you need to update(replace) the state you will need to dispatch an action, This action event must be captured by a reducer to replace your state.
- Actions are plane JS Objects describing the minimal change to the state/app. It must have a TYPE property.
- The UI ponents don't it self know how the changes are being done. All they know is that they need to dispatch an action.
- Pure function - Return value depends solely on the value of the arguments, do not have an side effects (network or db calls), idempotent (same arguments always predictability return the same value ), they do not modify the values passed to them
- Reducer - is a pure function that takes the whole state of the app and the action and returns the next state of the app (ensuring not to modify the current state, it has to return a new object) and has the following method signature:
(State,Action) => State;
So what does your actions look like for Async Flows (where you are retrieving data from network request)? When Async flow you using need to use some type of middleware http://redux.js/docs/advanced/Middleware.html.
In the actions below I have used a middleware called thunk.
actions.js:
export function receiveAllProducts(users){
return {
type: 'RECEIVED_ALL_USERS',
users: users
}
}
export function fetchALLUserData(){
return thunkLoadAllUserData;
}
const thunkLoadAllUserData = (dispatch) => {
let users = [];
users = //Some network request to get data
dispatch(receivedAllUserData(users));
});
}
So you would dispatch an action to fetchALLUserData
, which returns a thunk
function (redux middleware for Asynchronous Flows) to retrieve the users, which then calls receivedAllUserData
action that as a type : 'RECEIVED_ALL_USERS'
. This type is is captured by your reducer, which uses a pure function and Object.assign to return a new state (with the new users).
What does the reducer pure function look like ? reducers.js:
const initialState = {}
export default (currentState = initialState, action = {}) => {
switch (action.type) {
case 'RECEIVED_ALL_USERS':
return Object.assign({}, currentState, {
users: action.users,
});
case 'RECEIVE_ALL_PRODUCTS':
return Object.assign({}, currentState, {
productsAsObject: action.productsObject,
});
// ...other actions
default:
return currentState;
}
}
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. And therefore will copy the whole currentState and override your users attributes with the fetched user
Alternatively you can also use the object spread operator to update the state: http://redux.js/docs/recipes/UsingObjectSpreadOperator.html
You reducer should replace users
inside props
. And then change local state
inside ponentWillReceiveProps
method and set local state from props used this.setState{users: @nextProps.users}
If you need to set stuff on your state at the app startup, check up how the store and createStore
works. When you pass the preloadedState
attribute it will pass on that to your reducers.
If you are changing the users
array during the app execution, using AJAX calls or something like that, you use actions to do it.
So, you might dispatch an REQUEST_USERS
action. this action will send an AJAX request to your server, and on the success and error callbacks for this requests, you may dispatch REQUEST_USERS_SUCCESS
and REQUEST_USERS_FAILURE
actions, with the payload being the new users or an error message.
Check here for more information on how to handle AJAX requests properly with redux.
本文标签: javascriptWhat39s the way to update the whole state with ReduxStack Overflow
版权声明:本文标题:javascript - What's the way to update the whole state with Redux? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741639510a2389832.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论