对列表的一个元素所做的更改会影响到列表的所有元素

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,我知道一开始可能真的很难

【讨论】:

以上是关于对列表的一个元素所做的更改会影响到列表的所有元素的主要内容,如果未能解决你的问题,请参考以下文章

方案循环不会遍历列表中的所有元素

有啥方法可以保存用户对 HTML 页面所做的所有更改?

为啥 foo.append(bar) 会影响列表列表中的所有元素?

python 为啥我修改列表一个元素会导致所有元素都被修改

列表连接,将以“:”结尾的元素添加到列表中,将其他元素添加到子列表中

如何使选择列表出现在另一个元素上?