sta*_*lei 2 javascript redux ecmascript-next
我正在从本教程学习Redux,但我不知道下面的扩展运算符如何在对象和数组中工作.如果...state返回相同的东西,它在两种情况下如何工作?我认为它只会返回一个数组,因此它会在内部工作,SHUTTER_VIDEO_SUCCESS因为除了它之外它只会将状态内的任何内容传播到新数组中action.videos,但是如何在这个内部工作SELECTED_VIDEO呢?没有键放置它.扩展运算符从默认initialState权限中获取数组而不是键值对?
initialState.js
export default {
images: [],
videos: []
};
Run Code Online (Sandbox Code Playgroud)
someComponent.js
import initialState from './initialState';
import * as types from 'constants/actionTypes';
export default function ( state = initialState.videos, action ) {
switch (action.type) {
case types.SELECTED_VIDEO:
return { ...state, selectedVideo: action.video }
case types.SHUTTER_VIDEO_SUCCESS:
return [...state, action.videos];
default:
return state;
}
}
Run Code Online (Sandbox Code Playgroud)
Spread语法允许您将数组扩展到一个对象中(数组在技术上是对象,就像js中的所有内容一样).将数组扩展到对象时,它将key: value为每个数组项添加一对对象,其中键是索引,值是存储在数组中该索引处的值.例如:
const arr = [1,2,3,4,5]
const obj = { ...arr } // { 0: 1, 1: 2, 2: 3, 3: 4, 4: 5 }
const arr2 = [{ name: 'x' }, { name: 'y' }]
const obj2 = { ...arr2 } // { 0: { name: 'x' }, 1: { name: 'y' } }
Run Code Online (Sandbox Code Playgroud)
您还可以将字符串传播到数组和对象中.对于数组,它的行为类似于String.prototype.split:
const txt = 'abcdefg'
const arr = [...txt] // ['a','b','c','d','e','f', 'g']
Run Code Online (Sandbox Code Playgroud)
对于对象,它将按字符拆分字符串并按索引分配键:
const obj = { ...txt } // { 0:'a',1:'b',2:'c',3:'d',4:'e',5:'f',6:'g' }
Run Code Online (Sandbox Code Playgroud)
因此,当您将数组扩展到对象中时,您可能会获得一些有用的数据.但是,如果您给出的示例是您实际使用的示例,那么您将遇到问题.见下文.
=============
对于redux中的reducers,当您使用带有数组的spread语法时,它会将数组中的每个项目分散到一个新数组中.它与使用基本相同concat:
const arr = [1,2,3]
const arr2 = [4,5,6]
const arr3 = [...arr, ...arr2] // [1,2,3,4,5,6]
// same as arr.concat(arr2)
Run Code Online (Sandbox Code Playgroud)
对于一个对象,扩展语法将对key: value从一个对象扩展到另一个对象:
const obj = { a: 1, b: 2, c: 3 }
const newObj = { ...obj, x: 4, y: 5, z: 6 }
// { a: 1, b: 2, c: 3, x: 4, y: 5, z: 6 }
Run Code Online (Sandbox Code Playgroud)
这两种方法可以帮助您的数据在Reducer中保持不变.spread语法复制数组项或对象键/值,而不是引用它们.如果对嵌套对象或数组中的对象进行任何更改,则必须考虑到这一点,以确保获得新副本而不是变异数据.
如果您将数组作为对象键,则可以将整个对象扩展为新对象,然后根据需要覆盖单个键,包括需要使用扩展语法进行更新的数组的键.例如,对示例代码的更新:
const initialState = {
images: [],
videos: [],
selectedVideo: ''
}
// you need all of your initialState here, not just one of the keys
export default function ( state = initialState, action ) {
switch (action.type) {
case types.SELECTED_VIDEO:
// spread all the existing data into your new state, replacing only the selectedVideo key
return {
...state,
selectedVideo: action.video
}
case types.SHUTTER_VIDEO_SUCCESS:
// spread current state into new state, replacing videos with the current state videos and the action videos
return {
...state,
videos: [...state.videos, ...action.videos]
}
default:
return state;
}
}
Run Code Online (Sandbox Code Playgroud)
这显示更新状态对象和该对象的特定键是数组.
在您给出的示例中,您将动态更改状态的结构.它以数组开头,然后有时会返回一个数组(当SHUTTER_VIDEO_SUCCESS时)并且有时会返回一个对象(当SELECTED_VIDEO时).如果您想拥有一个reducer函数,则不会将initialState与视频数组隔离开来.您需要手动管理所有状态树,如上所示.但是你的reducer可能不应该根据动作切换它发回的数据类型.这将是一个不可预测的混乱.
如果你想将每个键分成一个单独的缩减器,你将有3个(图像,视频和selectedVideo)并用于combineReducers创建你的状态对象.
import { combineReducers } from 'redux'
// import your separate reducer functions
export default combineReucers({
images,
videos,
selectedVideos
})
Run Code Online (Sandbox Code Playgroud)
在这种情况下,每当您调度一个动作以生成完整的状态对象时,每个reducer都将运行.但是每个reducer只会处理它的特定键,而不是整个状态对象.因此,您只需要数组更新逻辑,如数组等.
| 归档时间: |
|
| 查看次数: |
7419 次 |
| 最近记录: |