我很反应和减少。 我正在尝试使用以下更新reducer中的状态。
export default function ReducersTodos(state = [], action) {
switch (action.type) {
case ADD_TODO:
state = [...state, {
id: state.length? state.length+1: 1,
text: action.value,
like: 0
}]
return state
break;
case ADD_LIKE:
state = state.map(todo => todo.id === action.id ? { ...todo, like: todo.like+1 } : todo)
return state
break;
case DIS_LIKE:
state = state.map(todo => todo.id === action.id ? { ...todo, like: todo.like-1 } : todo)
return state
break;
default:
return state
}
}
export class Like extends React.Component {
constructor(props){
super(props);
// This binding is necessary to make `this` work in the callback
this._handleClickAdd = this._handleClickAdd.bind(this);
this._handleClickSub = this._handleClickSub.bind(this);
}
_handleClickAdd = function(e) {
e.preventDefault();
this.props.addLike(this.props.task.id);
}
_handleClickSub = function(e) {
e.preventDefault();
this.props.disLike(this.props.task.id);
}
render() {
return (
<div>
Like {this.props.task.like}
<button className="btn btn-primary" onClick={this._handleClickAdd} {...this.props.task.like}>+</button>
<button className="btn btn-danger" onClick={this._handleClickSub} {...this.props.task.like}>-</button>
</div>
);
}
}
function mapDispatchToProps(dispatch) {
return {addLike: bindActionCreators(addLike, dispatch),
disLike: bindActionCreators(disLike, dispatch)}
}
//set props
const mapStateToProps = (state, ownProps) => ({todos : state.todos});
Like = connect(mapStateToProps, mapDispatchToProps)(Like)
当我尝试点击like
或dislike
按钮时。
它重新渲染整个列表,UI看起来很奇怪。
有没有办法只更新数组的一部分而不查看整个数组。
答案 0 :(得分:2)
mapStateToProps
,盯着它希望我&#39;注意到了什么,但我无法弄清楚发生了什么。我可以看到状态正在进入,并且正如你想要的那样改变,但是ui正在翻转。
最终我发现它here,在减速机附近,或mapStateToProps
。
this.props.todos.reverse().map(todo =>
<TodoSingleLi key={todo.id} task={todo}/>
)
此处的问题是reverse()
。来自mdn:
reverse
方法转换调用数组对象的元素,改变数组,并返回对数组的引用。
基本上,减速器以外的东西正在更新状态,更糟糕的是not doing so immutably,这解释了所遇到的奇怪程度。
幸运的是,这很容易解决:
this.props.todos.slice().reverse().map(todo =>
<TodoSingleLi key={todo.id} task={todo}/>
)
将slice()
添加到链中允许数组安全地变异。来自mdn:
slice
不会改变原始数组。它从原始数组返回浅拷贝元素。
谢谢你。很高兴找到一个改变的诚实到善的错误。
答案 1 :(得分:0)
您可以使用redux-auto简化代码。
<强>组件:强>
import actions from 'redux-auto'
export class Like extends React.Component {
render() {
const id = this.props.task.id
return (
<div>
Like {this.props.task.like}
<button className="btn btn-primary" onClick={()=>actions.todos.like({id})} {...this.props.task.like}>+</button>
<button className="btn btn-danger" onClick={()=>actions.todos.dislike({id})} {...this.props.task.like}>-</button>
</div>
);
}
}
//set props
const mapStateToProps = (state, ownProps) => ({todos : state.todos});
Like = connect(mapStateToProps)(Like)
<强>减速:强>
待办事项/ add.js
export default function (todos, payload) {
return [...todos, { id: todos.length + 1,
text: payload.value,
like: 0 }];
}
待办事项/ like.js
export default function (todos, payload) {
return todos.map(todo => todo.id === payload.id ? { ...todo, like: todo.like+1 } : todo);
}
待办事项/ dislike.js
export default function (todos, payload) {
return todos.map(todo => todo.id === payload.id ? { ...todo, like: todo.like-1 } : todo);
}
了解上述来源。 redux-auto会根据文件结构自动创建操作并将它们连接起来。文件夹名称成为状态属性的名称。文件夹中的文件是要在该州的该部分执行的操作。