我正在尝试创建一个用于收藏夹Card组件的开关,以使其在我的收藏夹.js组件中呈现。我正在使用Redux来存储状态,但是当我调度动作以将其添加到存储中或从存储中删除它们时,组件未呈现。我想我正在改变数组的状态。
这是减速器:
export function rootReducer(state = [], action) {
switch(action.type) {
case 'ADD_FAVORITE':
return state.concat(action.data);
case 'SUB_FAVORITE':
return state.filter(state => state.name !== action.data.name);
default:
return state;
}
}
我尝试使用Object.assign创建一个新的数组,但是由于传递到我的状态的数据本身在数组中,因此我无法使用store.getState()将它们映射到我的组件中。数组将嵌套在其内部。
这是我运行onClick来分派动作的功能:
toggleFavorites(e) {
if
(store.getState().includes(this.props.data))
{
console.log(this.props.data.name + ' removed from favorites');
store.dispatch({type: 'SUB_FAVORITE', data: this.props.data});
}
else{
console.log(this.props.data.name + ' added to favorites');
store.dispatch({type: 'ADD_FAVORITE', data: this.props.data});
}
this.props.data是通过引用JSON对象中的数组并将其映射到我的Card Component中传递的
这是我正在渲染的Card组件:
render() {
let {name, description, url , screenshot} = this.props.data;
return (
<div className="cardComponent">
<div className="CTA-container">
<div className="CTA-wrapper">
<div onClick={() => this.toggleFavorites(this.props.data)}className="CTA-icon"><IconComponent icon="favorite"/></div>
<a href={url} className="CTA-icon" target="_blank"><IconComponent icon="link"/></a>
</div>
</div>
<img src={screenshot} alt="" className="cardComponent_img"/>
<a href={url} className="cardComponent_name" target="_blank">{name}</a>
<p className="cardComponent_description">{description}</p>
</div>
我正在将这些Card组件渲染到avorites.js组件中,如下所示:
class Favorites extends Component {
constructor(props) {
super(props);
}
render() {
let cardComps = store.getState().map(data => {
return (
<CardComponent data = {data} />
)
})
return (
<div>
<div className="array-component">{cardComps}</div>
export default Favorites;
我对React和Redux还是很陌生,所以我不确定在设置组件时是否做错了什么。我只需要在用户从其收藏夹中添加或删除组件时重新渲染该组件。
答案 0 :(得分:2)
Redux会对更新状态的引用进行浅比较,并据此决定是否更新组件。
Array#concat
和Array#filter
都返回具有相同引用元素的新数组。因此,状态比较返回false
并且没有渲染。
假设action.data
是一维数组。
这应该起作用。
switch(action.type) {
case 'ADD_FAVORITE':
return [...state,action.data];
case 'SUB_FAVORITE':
return [...state.filter(state => state.name !== action.data.name)]
default:
return state;
}
答案 1 :(得分:0)
您还需要使用react-redux库的connect方法来监听商店更新。作为参考,我包含了代码。
In Reducer
switch(action.type) {
case 'ADD_FAVORITE':
return [...state,action.data];
case 'SUB_FAVORITE':
return [...state.filter(state => state.name !== action.data.name)]
default:
return state;
}
In Favorites.js Components
import { connect } from 'react-redux';
class Favorites extends Component {
constructor(props) {
super(props);
this.state = {
storeData: []
}
}
componentWillReceiveProps(nextProps){
if(nextProps.storeData !== this.state.storeData){
this.setState({
storeData: nextProps.storeData
})
}
}
render() {
const { storeData } = this.state;
let cardComps = storeData.map(data => {
return <CardComponent data = {data} />;
})
return (
<div className="array-component">{cardComps}</div>;
);
}
}
const mapStateToProps = state => {
return {
storeData: state
};
};
const connectedFavorites = connect(mapStateToProps)(Favorites);
export default connectedFavorites;