首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有人能告诉我我的Redux状态出了什么问题吗?

有人能告诉我我的Redux状态出了什么问题吗?
EN

Stack Overflow用户
提问于 2020-10-30 20:11:44
回答 2查看 45关注 0票数 1

编辑

状态未呈现的组件称为TournamentShow,它调用状态和我需要用于显示页面的任何函数。

内嵌套的条件是调用3个页面中的一个,基于

Tournament.Status === "Open"

Tournament.Status === "Closed",和

Tournament.Status === "Complete"

锦标赛展览:

代码语言:javascript
复制
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);

比赛放映屏幕:

代码语言:javascript
复制
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数组(在状态切换/重新呈现之前刚刚更新)

StartBracket显示来自ShowTournament的内容,这是已经在状态中设置的所有数据。

原始

我将用//注释标记哪一种情况不起作用

代码语言:javascript
复制
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个不同的组件

代码语言:javascript
复制
...

    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}
                />
            );
        }
    };

组件按钮:

Tournament.bracket.players

  • sets Tournament.status === "Closed"

  • Tournament.participants随机化并发送给Tournament.participants

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

问题是,它只显示了我在状态中已经装载的东西。(来自SHOW_TOURNAMENT的东西)

我发送随机用户列表的bracket.players数组在刷新页面之前不会显示。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-30 20:18:48

您需要对要更新的每个状态级别进行浅拷贝。此外,...state.showTournament.bracket.players.push(action.payload)只需尝试在push的返回值中传播,这正是数组的新长度。这不是你想要的。

代码语言:javascript
复制
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
      },
    },
  }
票数 1
EN

Stack Overflow用户

发布于 2020-10-30 22:03:14

德鲁的解决方案奏效了,只是为了将数组传递到另一个数组,语法是

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

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

日安

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64615150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档