有人可以告诉我我的 Redux 状态有什么问题吗?

Can someone show me what's wrong with my Redux state?

编辑

状态未在其中呈现的组件称为 TournamentShow,它调用状态以及我需要用于 Show 页面的任何函数。

其中嵌套有条件调用 3 个页面之一,基于

Tournament.Status === "Open",

Tournament.Status === "Closed",以及

Tournament.Status === "Complete"

锦标赛表演:

import React, { Component } from 'react';
import { SignUpPage, HostUI, StartBracket, Results } from './TournamentScreens';
import {
    showTournament,
    addParticipant,
    closeTournament,
    shuffleParticipants
} from '../../actions/tournamentActions';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Spinner } from 'reactstrap';

class TournamentShow extends Component {
    constructor(props) {
        super(props);
        this.onSignUp = this.onSignUp.bind(this);
        this.onStartTournament = this.onStartTournament.bind(this);
        this.onShuffleParticipants = this.onShuffleParticipants.bind(this);
    };

    componentDidMount() {
        const id = this.props.match.params.id;
        this.props.showTournament(id);
    };

    static propTypes = {
        tournament: PropTypes.object.isRequired,
        auth: PropTypes.object.isRequired
    };

    onSignUp(tournamentId, user) {
        this.props.addParticipant(tournamentId, user);
    };

    onShuffleParticipants(array) {
        let currentIndex = array.length, temporaryValue, randomIndex;   
        while(0 !== currentIndex) {
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;  
            temporaryValue = array[currentIndex];
            array[currentIndex] = array[randomIndex];
            array[randomIndex] = temporaryValue;
        }   
        return array;
    };

    onStartTournament(tourneyId) {
        const { participants } = this.props.tournament.showTournament;

        // Randomize participants
        let reorderedParticipants = [];
        const shuffledParticipants = this.onShuffleParticipants(participants);
        shuffledParticipants.forEach(participant => {
            reorderedParticipants.push(participant);
        });

        // Send new participants list to backend
        this.props.shuffleParticipants(tourneyId, reorderedParticipants);

        // Set Status to "Closed"
        this.props.closeTournament(tourneyId);
    };

    render() {
        console.log(this.props.tournament)
        const loading = this.props.tournament.loading || !this.props.tournament.showTournament;

        if(loading) {
            return <Spinner color="light" /> 
        } else {
            if(this.props.tournament.showTournament.status === "Complete") {
                return (
                    <Results />
                );
            } else if(this.props.tournament.showTournament.status === "Closed") {
                return (
                    <div>
                        <HostUI
                            tournament={this.props.tournament.showTournament}
                        />
                        <StartBracket
                            tournament={this.props.tournament.showTournament}
                        />
                    </div>
                );
            } else {
                return (
                    <SignUpPage
                        tournament={this.props.tournament.showTournament}
                        auth={this.props.auth}
                        onSignUp={this.onSignUp}
                        onStartTournament={this.onStartTournament}
                    />
                );
            }
        };
    };
};

const mapStateToProps = state => ({
    tournament: state.tournament,
    auth: state.auth
});

export default connect(mapStateToProps, 
    { showTournament, addParticipant, closeTournament, shuffleParticipants }
)(TournamentShow);

锦标赛展示画面:

import React from 'react';
import moment from 'moment';
import { TournamentSignUp, StartTournament } from './resources/buttons';
import { TournamentRules } from './resources/rulesets';
import { Button } from 'reactstrap';
import { Link } from 'react-router-dom';


// Status === "Open"
export const SignUpPage = ({ tournament, auth, onSignUp, onStartTournament }) => {
};


// Status === "Closed"
export const HostUI = ({ tournament }) => {
    const { players } = tournament.bracket;

    return (
        <div style={{color:"lightgrey"}}>
            <h1>Host UI</h1>
            {
                players && players.map(player => (
                    <div>
                        {player.username}
                    </div>
                ))
            }
        </div>
    );
};


export const StartBracket = ({ tournament }) => {
    const { title, hostedBy, participants } = tournament;

  return (
    <div className="text-center" style={{color:"lightgrey", backgroundColor: "#333333"}}>
      <h1>{ title }</h1>
      <h4>By { hostedBy }</h4>
      <h4>{participants && participants.length}-player bracket</h4>
      <br /><Link to="/">Back to Tournaments main page</Link>
    </div>
  );
};


// Status === "Complete"
export const Results = () => {
};

Status===Closed 显示了这两个核心组件。

HostUI 仅呈现 players 数组(刚刚在状态 switch/re-render 之前更新)

StartBracket 显示来自 ShowTournament 的内容,即已在状态

中设置的所有数据

原创------------------------

我会用//评论标记哪些情况不起作用

import { 
    GET_TOURNAMENTS, 
    SHOW_TOURNAMENT, 
    ADD_TOURNAMENT,
    ADD_TOURNAMENT_FAIL,
    EDIT_TOURNAMENT,
    EDIT_TOURNAMENT_FAIL,
    DELETE_TOURNAMENT, 
    TOURNAMENTS_LOADING, 
    TOURNAMENT_LOADING,
    USER_JOINS_TOURNAMENT, 
    TOURNAMENT_SIGN_UP_FAIL,
    TOURNAMENT_STATUS_UPDATE,
    TOURNAMENT_STATUS_FAILED,
    SHUFFLE_PARTICIPANTS,
    SHUFFLE_FAILED
} from '../actions/types';


const initialState = {
    tournaments: [],
    showTournament: {},
    loading: false,
};

export default function(state = initialState, action) {
    switch(action.type) {
        case GET_TOURNAMENTS:
            return {
                ...state,
                tournaments: action.payload,
                loading: false
            };

        case SHOW_TOURNAMENT:
            return {
                ...state,
                showTournament: action.payload,
                loading: false
            };

        case ADD_TOURNAMENT:
            return {
                ...state,
                tournaments: [action.payload, ...state.tournaments]
            };

        case DELETE_TOURNAMENT:
            return {
                ...state,
                tournaments: state.tournaments.filter(tournament => tournament._id !== action.payload)
            };

        case TOURNAMENTS_LOADING:
        case TOURNAMENT_LOADING:
            return {
                ...state,
                loading: true
            };

        case USER_JOINS_TOURNAMENT:
            return {
                ...state,
                ...state.showTournament.participants.push(action.payload)
            };

        case TOURNAMENT_STATUS_UPDATE:      // Occurs with SHUFFLE_PARTICIPANTS, which doesn't work
            return {
                ...state,
                ...state.showTournament.status = action.payload
            };

        case SHUFFLE_PARTICIPANTS:          // Does not work
            return {
                ...state,
                ...state.showTournament.bracket.players.push(action.payload)
            }

        case EDIT_TOURNAMENT:
        case ADD_TOURNAMENT_FAIL:
        case EDIT_TOURNAMENT_FAIL:
        case TOURNAMENT_SIGN_UP_FAIL:
        case TOURNAMENT_STATUS_FAILED:
        case SHUFFLE_FAILED:
            return {
                ...state,
            }

        default:
            return state;
    };
};

大部分都有效。
我确定我搞砸了的是 TOURNAMENT_STATUS_UPDATESHUFFLE_PARTICIPANTS,尽管状态更新按预期工作。

这是一个锦标赛应用程序,其显示页面基于 showTournament.status

呈现 3 个不同的组件
...

    if(loading) {
        return <Spinner color="light" /> 
    } else {
        if(this.props.tournament.showTournament.status === "Complete") {
            return (
                <Results />
            );
        } else if(this.props.tournament.showTournament.status === "Closed") {
            return (
                <div>
                    <HostUI
                        tournament={this.props.tournament.showTournament}
                    />
                    <StartBracket
                        tournament={this.props.tournament.showTournament}
                    />
                </div>
            );
        } else {
            return (
                <SignUpPage
                    tournament={this.props.tournament.showTournament}
                    auth={this.props.auth}
                    onSignUp={this.onSignUp}
                    onStartTournament={this.onStartTournament}
                />
            );
        }
    };

组件按钮:

更新页面并正确呈现 Status: "Closed" 页面。

问题是,它只显示我已经加载的状态。 (来自 SHOW_TOURNAMENT 的内容)

我将随机用户列表发送到的 bracket.players 数组在刷新页面后才会显示。

您需要浅复制您正在更新的每个级别的状态。此外,...state.showTournament.bracket.players.push(action.payload) 将简单地尝试散布在 push 的 return 值中,这只是数组的新长度。这不是你想要的。

case TOURNAMENT_STATUS_UPDATE:
  return {
    ...state,
    showTournament: {
      ...state.showTournament,
      status: action.payload,
    },
  };

case SHUFFLE_PARTICIPANTS:
  return {
    ...state,
    showTournament: {
      ...state.showTournament,
      bracket: {
        ...state.showTournatment.bracket,
        players: [...state.showTournament.bracket.players, ...action.payload], // spread payload array
      },
    },
  }

Drew 的解决方案有效,只是为了将一个数组传递给另一个数组,语法是

players: [...state.showTournament.bracket.players. ...action.payload]

而不是players: [...state.showTournament.bracket.players, action.payload]

美好的一天