【问题标题】:map function insert same data multiple times (React-Redux)映射函数多次插入相同的数据(React-Redux)
【发布时间】:2020-10-13 07:38:48
【问题描述】:

我正在尝试使用 React-Redux 实现 React Accordion 项目。

这是我的 Reducer 代码,其中我有一个 map 函数来对每个 id 一个一个地执行操作:

import * as actionTypes from '../actions/actions';

const initialState = {
    active: [
        { id: 1, status: false },
        { id: 2, status: false },
        { id: 3, status: false },
        { id: 4, status: false }
    ]
}
const reducer = (state = initialState, action) => {
    switch(action.type) {
        case actionTypes.ACTIVE_STATE:
            return {
                ...state,
                active: state.active.map((acdnobj) => {
                    const panel = document.querySelector(`.panel-${acdnobj.id}`);
                    return {
                        ...acdnobj,
                        acdnobj: acdnobj.id === parseInt(action.id) ? (
                            acdnobj.status = true,
                            panel.style.maxHeight = panel.scrollHeight + "px"
                        ) : (
                            acdnobj.status = false,
                            panel.style.maxHeight = '0px'
                        )
                    }
                }) 
            }
        default:
    }
    return state; 
}
export default reducer;

这是我的手风琴,我有另一个地图功能来增加身份证号码:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actionTypes from '../store/actions/actions';

class Accordion extends Component {
    localDispatch = (key) => {
        this.props.expandAccordion(key.target.value);
    }
    render() {
        return (
            <div>
                {this.props.accordions.map((accordion, index) => {
                    return (
                        <div key={index}>
                            <button value={ index + 1 } className={`accordion ${accordion.status}`}
                            onClick={this.localDispatch.bind(this)}>
                                {this.props.title}
                            </button>
                            <div className={`panel panel-${accordion.id}`}>
                                {this.props.content}
                            </div>
                        </div>
                    )
                })}
            </div>
        );
    }
}
const mapStateToProps = (state) => {
    return {
        accordions: state.data.active
    };
}
const mapDispatchToProps = (dispatch) => {
    return {
        expandAccordion: (key) => dispatch({type: actionTypes.ACTIVE_STATE, id: key})
    };
}
export default connect(mapStateToProps, mapDispatchToProps)(Accordion);

在 App.js 组件中,我有另一个映射函数来从 excel 文件中获取数据:

if(list.length > 0) {
      accordionDIV = list[0].map((d, index) => (
        <Accordion _key={index}
          title = {
            <Table>
              <tr key={d.ID}>
                <td>{d.ID}</td>
                <td>{d.Mail}</td>
                <td>{d.Name}</td>
                <td>{d.PhoneNo}</td>
                <td>{d.City}</td>
                <td>{d.Date}</td>
                <td>{d.Time}</td>
              </tr>
            </Table>
          }
          content = {
            <div>
              <p className="header">
                <span style={{color:"#3c67a5"}}>Shipping Address:</span>
                292 Naqashband Colony, Near rabbania Mosque, Multan
              </p>
              <Table size="sm" className="content">
                <thead>
                  <tr>
                    <th style={{width:"10%"}}></th>
                    <th style={{width:"15%"}}>Article No</th>
                    <th style={{textAlign:"left", width:"30%"}}>Product Name</th>
                    <th style={{width:"15%"}}>Quantity</th>
                    <th style={{width:"15%"}}>Price</th>
                    <th style={{width:"20%"}}>Total Amount</th>
                  </tr>  
                </thead>
                <tbody>
                  {list[1].map((c) => 
                    c.ID === d.ID ? (
                      <tr key={c.ID}>
                        <td> <FontAwesomeIcon icon={faTrashAlt} size="xs" className="icon" /> </td>
                        <td>{c.ArticleNo}</td>
                        <td style={{textAlign:"left"}}>{c.ProductName}</td>
                        <td>{c.Quantity}</td>
                        <td>{c.Price}</td>
                        <td>{c.TotalAmount}</td>
                      </tr>
                    ) : null
                  )}
                </tbody>
              </Table>
          </div>
          }
        />
      ))
    }

问题是在运行时我有多个手风琴用于相同的数据。

建议我现在可以做些什么来解决这个问题。

【问题讨论】:

  • 你能分享一下你得到的活动状态吗?谢谢
  • 如果我单击手风琴 1,活动状态索引为“0”,单击手风琴 2 时活动状态索引为“1”,依此类推。
  • 你知道你在你的 reducer 中做状态突变,而且直接的 DOM 操作是一个副作用(应该是一个纯函数)和一个非常重要的反应反模式?
  • 我也觉得在reducer中操作DOM元素不是一个合适的方法。
  • 您能否将您的问题重现到一个可以实时调试的running 代码盒中?更清楚地解释问题?有点难以理解“问题是在运行时我有多个手风琴用于相同的数据。”

标签: javascript reactjs react-redux accordion


【解决方案1】:
import * as actionTypes from '../actions/actions';

const initialState = {
    active: [
        { id: 1, status: false },
        { id: 2, status: false },
        { id: 3, status: false },
        { id: 4, status: false }
    ]
}
const reducer = (state = initialState, action) => {
    switch(action.type) {
        case actionTypes.ACTIVE_STATE:
            let newActive = [...state.active];
            newActive = newActive.map((acdnobj) => {
                  const panel = document.querySelector(`.panel-${acdnobj.id}`);
                  panel.style.maxHeight = (acdnobj.id === parseInt(action.id)) ? panel.scrollHeight + "px" : '0px';
                  return {
                      ...acdnobj,
                      status: acdnobj.id === parseInt(action.id)
                  }
            }) 
            
            return {
                ...state,
                active: newActive
            }
        default:
    }
    return state; 
}
export default reducer;

这可能是 Javascript 上的数组可变问题,因此您可以使用上述代码或尝试使用 immutable.js

【讨论】:

  • 我试过你的这仍然返回多个手风琴并且不打开
  • 减速机工作完美。我认为问题出在地图功能上,我已经使用过很多次了。而且不知道怎么解决这个问题
  • @MuzamilHussain 能否告诉我 redux 值(我的意思是多个值)的结果?
  • > 4[ {...}, {...}, {...}, {...} ], 4[ {...}, {...}, {...}, {...} ] 等相同的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-09
  • 2019-03-19
  • 2017-12-14
  • 2021-12-10
  • 2017-06-01
相关资源
最近更新 更多