Redux和React。不改变内容

时间:2018-05-14 19:50:52

标签: reactjs redux

我正在使用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;
    }
}

Archive with all my code

2 个答案:

答案 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