【问题标题】: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);

【问题讨论】:

    标签: reactjs redux react-redux redux-form redux-thunk


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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 2018-05-27
      • 2011-09-15
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      相关资源
      最近更新 更多