簡體   English   中英

有人可以告訴我我的 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數組(在狀態切換/重新渲染之前剛剛更新)

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

組件按鈕:

  • 隨機化Tournament.participants並將其發送到Tournament.bracket.players
  • 設置Tournament.status === "Closed"

這會更新頁面並正確呈現Status: "Closed"頁面。

問題是,它只顯示我已經在狀態中加載的任何內容。 (來自SHOW_TOURNAMENT東西)

我將隨機用戶列表發送到的bracket.players數組在我刷新頁面之前不會顯示。

您需要淺復制您正在更新的每個狀態級別。 此外, ...state.showTournament.bracket.players.push(action.payload)將簡單地嘗試傳播push的返回值,這只是數組的新長度。 這不是你想要的。

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]

再會

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM