我正在使用react和redux。 当我做排序时,内容不会重新呈现
代码:
case SORT_BY:
//if (action.payload.group_id !== undefined)
groups = state.groups;
groups.map(
(group, groupId) => groupId === action.payload.group_id
? new Group (
group.title, group.tasks.sort(
function (a , b)
{return a.title > b.title;}
)
)
: group
);
return {groups};
我知道问题出在这里,因为redux比较旧对象和新对象。在这个比较中它们是相同的。那么,我应该怎么做才能立即改变? (当我要做另一个功能时,内容会改变。)
Here I have clicked to sortButton on the TaskGroup#1 - 内容未发生变化
Here I have added new task - 内容发生了变化,而且,我得到了排序任务的列表
应用代码(内容重新呈现的React类)
import React, {PureComponent} from 'react';
import {connect} from 'react-redux';
import Group from './Group'
import AddGroup from './AddGroup'
import SortBy from '../components/Sort'
class App extends PureComponent {
render() {
const groups = this.props.groups.map((group, index) => (<Group key={index} index={index} {...group} />));
return (
<div>
<h1>Tasks</h1>
<SortBy/>
<ul>
<AddGroup/>
{groups}
</ul>
</div>
);
}
}
// groups from redux store is mapped to this.props.groups
export default connect(
(state) => ({
groups: state.groups
})
)(App);
小组js
import React, {PureComponent} from 'react';
import Task from './Task'
import AddTask from './AddTask'
import Sort from './Sort'
import {deleteGroup, reName} from "../actions/group";
import {connect} from "react-redux";
export class Group extends PureComponent {
onDeleteClick = () => {
const { deleteGroup, title } = this.props;
// dispatch action
deleteGroup(title);
};
onRenameClick = () => {
const { reName, title } = this.props;
// dispatch action
reName(title, "group");
};
render() {
// this.props.index contains group id (index in groups array)
const tasks = this.props.tasks.map((task, index) => (
<Task key={index} index={index} group={this.props.index} {...task} />));
return (
<div>
<h2>{this.props.title} <input type="button" value="Delete" onClick={this.onDeleteClick}/><input type="button" value="Rename" onClick={this.onRenameClick}/></h2>
<ul>
<AddTask group={this.props.index} />
<Sort whatToSort={this.props.index}/>
{tasks}
</ul>
</div>
);
}
}
export default connect(null, {deleteGroup, reName})(Group);
所有reducer的代码
import Task from '../models/Task';
import Group from '../models/Group';
import {ADD_TASK, DELETE_TASK, TOGGLE_TASK} from '../actions/task';
import {ADD_GROUP, DELETE_GROUP, RENAME_GROUP} from "../actions/group";
import {SORT_BY} from "../actions/functions";
let g1 = new Group('Základní část',);
let g2 = new Group('Bonusová část',);
g1.addTask(new Task('přeškrtnutí splněného úkolu',true));
g1.addTask(new Task('přidání nové skupiny',true));
g1.addTask(new Task('odstranění skupiny',true));
g1.addTask(new Task('přidání a vypisování atributu počtu bodů ke každému úkolu'));
g1.addTask(new Task('přepočítání bodů při změně stavu (splnění) úkolu'));
g2.addTask(new Task('editace úkolu (názvu)',true));
g2.addTask(new Task('editace skupiny (názvu)',true));
g2.addTask(new Task('řazení úkolů'));
g2.addTask(new Task('řazení skupin'));
const initialState = {
groups: [g1, g2]
};
export default function mainReducer(state = initialState, action) {
let groups;
switch (action.type) {
case ADD_TASK:
// add new task to given group and left other groups intact
groups = state.groups.map(
(group, groupId) => (groupId === action.payload.groupId
? new Group(group.title, [...group.tasks, new Task(action.payload.title)])
: group
)
);
return {groups};
case DELETE_TASK:
groups = state.groups.map(
// removes task (filter group tasks) from given group and left other groups intact
(group, groupId) => (groupId === action.payload.groupId
? new Group(group.title, group.tasks.filter(
(task, taskId) => (taskId !== action.payload.taskId))
)
: group
)
);
return {groups};
case TOGGLE_TASK: {
// update task in given group and left other groups intact
groups = state.groups.map(
(group, groupId) => (groupId === action.payload.groupId
? new Group(group.title, group.tasks.map(
// update given task and left other tasks intact
(task, taskId) => (taskId === action.payload.taskId
? {...task, done: !task.done}
: task
))
)
: group
)
);
return {groups};
}
case ADD_GROUP:
let doesExist = false;
groups = state.groups.map(
(group) =>
{
if (group.title === action.payload.title)
doesExist = true;
return group;
}
);
doesExist
? alert("This tasks group is already exist. Try to choose other name")
: groups.push(new Group(action.payload.title));
return {groups};
case DELETE_GROUP:
groups = [];
state.groups.map(
(group) =>
{
if (group.title !== action.payload.title)
groups.push(group);
return group;
}
);
return {groups};
case RENAME_GROUP:
let newTitle = prompt("Please enter new name of the " + action.payload.type);
groups = state.groups.map(
(group) =>
{
switch (action.payload.type)
{
case "group":
if (group.title === action.payload.title)
group.title = newTitle;
return group;
case "task":
return new Group(
group.title, group.tasks.map(
(task) =>
{
if (task.title === action.payload.title)
task.title = newTitle;
return task;
}
)
);
default:
return group;
}
}
);
return {groups};
case SORT_BY:
//if (action.payload.group_id !== undefined)
groups = [...state.groups];
const newgroups = groups.map(
(group, groupId) => groupId === action.payload.group_id
? new Group (
group.title, group.tasks.sort(
function (a , b)
{return a.title > b.title;}
)
)
: group
);
return { newgroups };
default:
return state;
}
}
答案 0 :(得分:0)
代码显然缺少一些必要的信息才能使其可验证,但有一件事是肯定的,你忘了从groups.map
返回新数组,因为map没有改变任何地方,它返回新的具有映射值的数组。
所以试试这个,也许它可以解决问题:
groups = groups.map( ...
return {groups}
答案 1 :(得分:0)
map()方法创建一个新数组,其中包含调用a的结果 为调用数组中的每个元素提供了函数。
map方法返回一个新数组。它不像你期望的那样改变原始数组。
另外,只看你的逻辑,我认为你会从@Override
public int hashCode() {
return Objects.hashCode(person1, person2);
}
数组方法中获益更多,而不是reduce