问题描述
我正在尝试使用React-Redux实施React Accordion项目。
这是我的 Reducer 代码,其中有一个映射函数,可以对每个id逐一执行操作:
import * as actionTypes from '../actions/actions';
const initialState = {
active: [
{ id: 1,status: false },{ id: 2,{ id: 3,{ 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>
}
/>
))
}
问题在于,在运行时我有多个手风琴用于同一数据。
建议我现在可以解决此问题。
解决方法
import * as actionTypes from '../actions/actions';
const initialState = {
active: [
{ id: 1,status: false },{ id: 2,{ id: 3,{ 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