javascript - 在 react redux 中唯一地计算某些元素
问题描述
我有一个反应组件,它将加载第 3 方内容,因此需要一个索引。该索引基于位置属性,它是一个枚举,并且对于具有相同位置的每个组件都会递增。
例子:
位置 a = 索引 a-1
位置 b = 索引 b-1
位置 a = 索引 a-2
我不想将计数器存储在函数或其他东西中,因为应用程序应该是无状态的,以避免在服务器端呈现它时出现问题。因此,我尝试将计数器(需要不时重置)存储在 redux 中,但这会导致问题,因为动作的调度是异步的,我无法设法在两个渲染之间的某个位置增加索引成分。因此,即使在 redux 状态下的索引增加时,我也总是得到所有位置的索引 1。
const Mycomponent = (props) => {
// this should avoid to update the position after the initialization
const [positionCount] = useState(props.positionCount);
// this should update the counter but its fired too late so that the 2. component will get the same counter as the first one
if (positionCount === props.positionCount) {
props.increasePositionCounter(props.position);
}
...
}
@Edit 该位置是从上面的组件中给出的,不应更改。但是根据已经渲染了多少具有相同位置的组件,我们需要一个不同的索引。
增量代码如下所示:
export function exampleReducer(state, action) {
let newState;
switch (action.type) {
// ...
case actions.INCREASE_COUNTER:
newState = {
...state,
counter: {
...state.counter,
[action.payload.position]: state.counter[action.payload.position] + 1
}
};
break;
// ...
}
return newState;
}
当我渲染一个位置为 a 的组件时,它应该获得索引 a-1。现在我渲染另一个具有相同位置 a 的组件,它应该获得索引 a-2 等等。但是然后我用另一个位置渲染另一个组件,比如说b,它应该得到索引b-1。但是我不知道在哪里可以跟踪到目前为止每个位置渲染了多少组件。希望这有助于更好地理解。
@Edit2: 我已经与第 3 方内容的开发人员进行了交谈,他们告诉我另一种我根本不需要索引的方式。所以这个问题对于我的情况来说有点解决了。但是,如果有人知道如何解决该问题,请随时发布!
解决方案
您可以简单地跟踪所有渲染的子组件以及它们在您的状态中各自的位置和索引。
这样,您可以轻松地检索具有特定位置的元素的最大使用索引或删除某些项目:
//dependencies
const { render } = ReactDOM,
{ createStore } = Redux,
{ connect, Provider } = ReactRedux
//store initialization
const defaultState = {
children:[]
},
appReducer = (state=defaultState, action) => {
switch(action.type){
case 'APPEND_CHILD': {
const {children} = state,
{payload:pos} = action
if(!pos.length) return state
const maxIndex = Math.max(0,...children
.filter(({position}) => position == pos)
.map(({index}) => index)
)
return {...state, children: [...state.children,{position:pos, index:maxIndex+1}]}
}
default: return state
}
},
store = createStore(appReducer)
//append child component
const AppendChildForm = ({pos,onAppendChild}) => {
return (
<form onSubmit={e=>(e.preventDefault(),onAppendChild(pos),e.target.reset(),pos=null)}>
<label>Child position<input maxLength="1" onKeyUp={event => pos=event.target.value}></input></label>
<button>Append Child</button>
</form>
)
}
//append child container
var mapDispatchToProps = dispatch => ({onAppendChild: pos => dispatch({type:'APPEND_CHILD',payload:pos})})
const AppendChildContainer = connect(null,mapDispatchToProps)(AppendChildForm)
//child component
const ChildComponent = ({position,index}) => <div>My position is {position} and my index is {index}</div>
//parent component
const ParentComponent = ({children}) => (
<div>
{children.map(({index,position},key) => <ChildComponent index={index} position={position} key={key} />)}
</div>
)
//parent container
var mapStateToProps = ({children}) => ({children:[...children]})
const ParentContainer = connect(mapStateToProps)(ParentComponent)
//provider
render(
<Provider store={store}>
<AppendChildContainer />
<ParentContainer />
</Provider>,
document.getElementById('root')
)
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script><script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script><script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.4/redux.min.js"></script><script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.1/react-redux.min.js"></script><div id="root"></div>
推荐阅读
- angular - Angular + .net Core 3 + Azure App Service - 仅在特定路由上允许 HTTP?
- node.js - URIError:无法解码参数 - 编码二进制图像 Filepond
- javascript - switch 语句不识别输入
- listview - Xamarin MVVM 从可绑定的 FlexLayout 中选择项目,类似于在 ListView 上选择项目
- react-native-android - 当我使用代码 react-native init App1 表示此错误时,我无法创建 react-native
- php - 如何在magento2中显示菜单的所有类别项
- typescript - 从 ejs-dropdownlist 中获取选定的项目对象
- vb.net - 如何模拟 OleDbDataAdapter(查询,connStr)
- mongodb - 具有 persistenceVolumeClaims 的 IBM Cloud stable/mongodb 图表
- python - Docker 无法连接到 Flask