对列表的一个元素所做的更改会影响到列表的所有元素
Posted
技术标签:
【中文标题】对列表的一个元素所做的更改会影响到列表的所有元素【英文标题】:Change done on one element of the list is affected to all elements of the list 【发布时间】:2019-11-06 06:19:25 【问题描述】:我必须显示用户列表,单击按钮时我想在按钮内显示文本。 UserHeader 是我从我的记录列表 (PostList) 中导入的组件。我意识到,一旦我单击按钮,所有列表元素的操作都会受到影响,我认为这是因为减速器的状态数组被记录填充,并且每次显示 UserHeader 时,它都会显示按钮内的文本。我只想在我已经处理的列表元素上显示文本,而不是整个列表。请帮助我如何使用 redux 做到这一点。我指的是UserHeader上按钮的selectPost()函数onClick
// reducers.js
export const Reducer_posts = (state=[], action) =>
switch (action.type)
case 'FETCH_POSTS':
return action.payload
default:
return state;
;
export const Reducer_users = (state=[], action) =>
switch (action.type)
case 'FETCH_USER':
return [...state, action.payload];
default:
return state;
;
export const Reducer_select = (state=[], action) =>
switch (action.type)
case 'SELECT_POST':
return action.payload;
case 'DELETE_SELECT':
return null;
default:
return state;
;
//UserHeader.js
import React from 'react';
import connect from 'react-redux';
import fetchUser, selectPost, deleteSelect from '../actions';
class UserHeader extends React.Component
componentDidMount ()
this.props.fetchUser(this.props.userId);
render()
console.log(this.props.select)
if(!this.props.user)
return <div> Loading... </div>
return <button onClick=this.props.selectPost className="header"> this.props.select </button>
const mapStateToProps = (state, ownProps) =>
return
user: state.users.find(user => user.id === ownProps.userId),
select: state.select
;
export default connect(mapStateToProps, fetchUser, selectPost, deleteSelect )(UserHeader);
//PostList.js
import React from 'react';
import connect from 'react-redux';
import fetchPosts, selectPost from '../actions';
import UserHeader from './UserHeader'
class PostList extends React.Component
componentDidMount()
this.props.fetchPosts();
renderList()
return this.props.posts.map(post =>
return (
<div className = "item" key=post.id>
<i className="large middle aligned icon user" />
<div className="content">
<div className = "description">
<h2> post.title </h2>
<p> post.body </p>
</div>
<UserHeader userId = post.userId/>
</div>
</div>
)
)
render()
return <div className = "ui relaxed divided list"> this.renderList() </div>;
;
const mapStateToProps = state =>
return posts: state.posts, select: state.select ;
;
export default connect( mapStateToProps, fetchPosts, selectPost )(PostList);
【问题讨论】:
【参考方案1】:您应该使用 id 存储在状态元素上,这样您就可以随心所欲地管理它。 示例
// Let's imagine that this is your initial state. State here is an object of an x
// object that contains n-object that represents your button.
//
const state =
myButtons: [
id: "unique_id",
.
.
,
...
],
selectedBtn: -1,
在这种情况下,您可以轻松地获得想要通过操作传递 id 的按钮,因此减速器将类似于:
export const Reducer_posts = (state=[], action) =>
switch (action.type)
case 'FETCH_POSTS':
const newState = Object.assign(, state);
newState.myButtons.concat(action.payload)
return Object.assign(, newState)
default:
return state;
;
export const Reducer_select = (state=[], action) =>
switch (action.type)
case 'SELECT_POST': // I think this is fired on click on a button
const newState = Object.assign(, state);
newState.selectedBtn = action.payload.btnId;
return Object.assign(, newState);
case 'DELETE_SELECT': // when you have to delete a button
const newState = Object.assign(, state);
newState.myButtons =
newState.myButtons.filter((el) => el.id !== action.payload.id)
return Object.assign(, newState);
default:
return state;
;
现在,如果您必须使用这样的结构更改文本,您可以使用过滤器轻松访问此数组并获取您想要的按钮。在您的代码 sn-p 上,当您的代码到达 reducer 时,它只是返回 action.payload,这实际上是错误的,因为 redux 的原则之一说状态应该是不可变的。我从 here 那里学习了 redux,我知道一开始可能真的很难
【讨论】:
以上是关于对列表的一个元素所做的更改会影响到列表的所有元素的主要内容,如果未能解决你的问题,请参考以下文章
为啥 foo.append(bar) 会影响列表列表中的所有元素?