TL; DR:如果一个可重用的组件有一些复杂的逻辑来管理自己的状态(想想:一个带有autocompleter,emoji等的facebook评论textarea)如何使用store,actions和reducers来管理整个网站上传播的这个组件的多个实例的状态?
考虑官方redux回购中的real-world example。 我们在其中:
items
和renderItem
的方式。特别是RepoPage
使用User
组件来显示为回购标记加星标的每个用户,而UserPage
使用Repo
组件来显示每个已加星标的回购广告。假设我真的希望状态的所有都在Redux中。
特别是,我希望每个RepoPage和UserPage上的每个List的状态都由Redux管理。这个例子已经由一个聪明的三级深树来处理:
store.pagination
)store.pagination.starredByUser
,store.pagination. stargazersByRepo
)store.pagination.starredByUser[login]
,store.pagination. stargazersByRepo[repo]
)我觉得这三个级别也对应于:组件类型,父类型,父ID。
但是,我不知道如何扩展这个想法,以处理List组件本身有很多孩子的情况,其中一个状态值得在Redux中跟踪。
特别是,我想知道如何实现一个解决方案:
User
组件保持不变Repo
组件有一个切换其背景颜色的按钮Repo
组件的状态由Redux管理(我很高兴使用Redux的一些扩展程序,它仍然使用Reducer,但不想使用"只需将它保持在React本地状态",为了这个问题的目的)
到目前为止我的研究:
action.type
由子串组成,这些子串告诉通过组件的路径'树。 this comment中的OTOH棱镜作者tomkis解释说,Redux缺少的榆树建筑最重要的部分是行动的构成action.type
来通过{{1}中的安装路径来识别组件实例这也与组件树中的路径相对应,因为它是由组件手动构造的方式store
标识符,这样可以非常容易地检查hWnd
是否适合你,并决定在哪里应该是action
中的州。 答案 0 :(得分:2)
我将尝试解释一个受Elm lang启发并被移植到Typescript的想法:
我们说我们的组件非常简单,具有以下状态
interface ComponentState {
text: string
}
可以通过以下两个操作来减少组件。
interface SetAction {
type: 'SET_VALUE', payload: string
}
interface ResetAction {
type: 'RESET_VALUE'
}
为这两个动作键入联合(请查看不同的打字稿联盟):
type ComponentAction = SetAction | ResetAction;
对此的减速器应该有以下签名:
function componentReducer(state: ComponentState, action: ComponentAction): ComponentState {
// code
}
现在来"嵌入"我们需要在较大的组件中使用这个简单的组件将数据模型封装在父组件中:
interface ParentComponentState {
instance1: ComponentState,
instance2: ComponentState,
}
由于redux中的操作类型需要全局唯一,因此我们无法为Component实例调度单个操作,因为它将由两个实例处理。其中一个想法是使用以下技术将单个组件的操作包装到父操作中:
interface Instance1ParentAction {
type: 'INSTNACE_1_PARENT',
payload: ComponentAction,
}
interface Instance2ParentAction {
type: 'INSTNACE_2_PARENT',
payload: ComponentAction,
}
父母行动联盟将具有以下签名:
type ParentComponentAction = Instance1ParentAction | Instance2ParentAction;
这项技术最重要的是 - 父减速器:
function parentComponentReducer(state: ParentComponentState, action: ParentComponentAction): ParentComponentState {
switch (action.type) {
case 'INSTNACE_1_PARENT':
return {
...state,
// using component reducer
instance1: componentReducer(state.instance1, action.payload),
};
//
}
}
使用被歧视的联合会为父母和儿童减少者提供类型安全。