编辑
状态未在其中呈现的组件称为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 = () => {
};
CCD_ 4显示了这两个中心组件。
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_UPDATE
和SHUFFLE_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]