我有一个父组件(LeagueSelect)和一个子组件TeamSelect。
LeagueSelect是一个React Native模式。
当我打开LeagueSelect时,在LeagueSelect模式中进行调整,折叠模式,然后再次打开,状态更改将保留。
如果我打开LeagueSelect,在LeagueSelect模式中对TeamSelect进行调整,折叠模式,然后再次打开它,状态更改将不会保留。
为了提供上下文,当模式(LeagueSelect)打开时,它是这样的;第一个红色框是LeagueSelect的一部分,第二个红色框是TeamSelect的一部分:
这是我的LeagueSelect组件;我认为问题是在setModalVisible中发生的,因为当我进行console时,控制台日志会读取正确的状态。在componentWillUnmount上记录该状态:
class LeagueSelect extends Component {
constructor(props) {
super(props)
this.state = {
modalVisible: false,
checked: [],
checkedLeagues: [],
uncheckedLeagues: [],
checkMessage: '',
firstString: []
}
}
setModalVisible(visible) {
this.setState({modalVisible: visible})
if(this.state.checked.length === 0) {
this.props.league.map(
(v, i) => {
this.state.checked.push(true)
this.state.checkedLeagues.push(v.acronym)
}
)
}
this.setState({ checkMessage: '' })
matchedTeams = []
if(undefined !== this.props.teamObject) {
this.props.teamObject.map(
(v, i) => {
if(this.state.checkedLeagues.includes(v.league.acronym)){
matchedTeams.push(v.team_name)
}
}
)
}
queryString = []
//encodes the teams that have their leagues selected
matchedTeams.map(
(v, i) => {
if (queryString.length < 1) {
queryString.push(`?team=${v}`)
} else if (queryString.length >= 1 ) {
queryString.push(`&team=${v}`)
}
}
)
queryString = queryString !== undefined ? queryString.join('') : ''
axios.get(`http://localhost:4000/reports${queryString}`)
.then(response => {
this.props.loadCards(response.data)
})
}
componentDidMount() {
this.props.loadLeagues()
this.props.loadTeams()
}
componentDidUpdate(){
console.log(this.props.checkedLeagues)
console.log('in league - in update - checked Teams', this.props.checkedTeams)
this.props.changeLeagues(this.props.league, this.state.checkedLeagues, this.props.checkedTeams, this.props.queryTeams, this.props.teamObject)
}
render(){
return (
<View style={{ position: 'relative'}}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}
>
<View
style={{
marginTop: 100
}}
>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}
>
<Image
source={require('../assets/exit.png')}
style={{
height: 20,
width: 20,
left: 320,
resizeMode: 'contain'
}}
/>
</TouchableHighlight>
<Text
style={{
paddingTop: 8,
paddingLeft: 5,
fontSize: 15,
fontFamily: 'Helvetica',
fontSize: 13
}}
>LEAGUE SELECT</Text>
<View
style={{
flexDirection:"row",
paddingLeft: 10
}}
>
{this.props.league === null ?'' : this.props.league.map(
(v, i) => {
return(
<View
key={i}
style={{
alignSelf: 'flex-end',
flexDirection:"row",
top: 4,
paddingRight: 10
}}
>
<Check
checked={this.state.checked[i]}
index={i}
value={v.acronym}
changeCheck={this.changeCheck}
style={{
paddingRight: 10
}}
/>
</View>
)
}
)}
</View>
<Text
style={{
paddingLeft: 10,
paddingTop: 12,
fontStyle: 'italic',
color: '#F4AF0D'
}}
>{this.state.checkMessage}</Text>
<TeamSelect />
</View>
</Modal>
<TouchableHighlight
onPress={() => {
this.setModalVisible(true);
}}>
<Icon
style={{
position: 'absolute',
top: -34,
right: 10,
fontSize: 25,
color: 'grey'
}}
name='settings'
/>
</TouchableHighlight>
</View>
);
}
}
function mapStateToProps(state) {
return {
league: state.league.league,
team: state.team.team,
checkedLeagues: state.league.checkedLeagues,
checkedTeams: state.league.checkedTeams,
queryTeams: state.league.queryTeams,
teamObject: state.league.teamObject
}
}
export default connect(mapStateToProps, { loadCards, loadLeagues, loadTeams, changeLeagues })(LeagueSelect)
这是TeamSelect组件,在其中选择了第二个红色框:
class TeamSelect extends Component {
constructor(props) {
super(props)
this.state = {
checked: [],
checkedTeams: [],
teamObject: [],
queryString: [],
accordionStatus: [true, true, true]
}
}
componentDidMount(){
console.log('did mount - checked Teams State', this.state.checkedTeams)
//updates checked teams on load
if(this.state.count === false && this.state.checkedTeams.length === 0 && this.state.checked.length === 0){
this.setState({ count: true})
this.props.team.map(
(v, i) => {
if(this.props.checkedLeagues.includes(v.league.acronym)) {
this.state.checked.push(true)
this.state.checkedTeams.push(v.team_name)
this.state.teamObject.push(v)
} else if (this.state.checkedTeams !== undefined) {
this.state.checked.push(false)
}
}
)
this.forceUpdate()
}
}
componentWillUnmount(){console.log("unmount - count", this.state.count)
console.log('will unmount - checked Teams State', this.state.checkedTeams)
}
componentDidUpdate(){
this.props.changeLeagues(this.props.league, this.props.checkedLeagues, this.state.checkedTeams, this.state.queryString, this.state.teamObject)
}
changeCheck = (index, name, teamObject) => {
//updates checked team state
//prevents all teams being unselected
if(name === this.state.checkedTeams[0]) {
this.setState({ checkMessage: `Don't you want something to look at?` })
} else {
if(!this.state.checkedTeams.includes(name)){
this.state.checkedTeams[this.state.checkedTeams.length] = name
this.setState({ checkedTeams: [...this.state.checkedTeams] })
//sets team object with new team object
this.state.teamObject[this.state.teamObject.length] = teamObject
this.setState({ teamObject: this.state.teamObject })
} else {
newChecked = this.state.checkedTeams.filter(v => { return v !== name})
this.setState({ checkedTeams: newChecked })
//removes team object and sets new state
newObjectChecked = this.state.teamObject.filter(v => { return v.team_name !== teamObject.team_name})
this.setState({ teamObject: newObjectChecked })
}
//updates checkbox for specific space
this.state.checked[index] = !this.state.checked[index]
this.setState({ checked: this.state.checked })
}
}
changeTeamSelect = (index) => {
this.state.accordionStatus[index] = !this.state.accordionStatus[index]
this.setState({ accordionStatus: this.state.accordionStatus})
}
render(){
return(
<View>
<View>
<Text
style={{
fontFamily: 'Helvetica',
fontSize: 13,
paddingLeft: 5,
paddingBottom: 5
}}
onPress={()=> this.changeTeamSelect(0)}
>
NFL TEAM SELECT
</Text>
</View>
{
this.state.accordionStatus[0] === false ? null :
<View
style={{
flexDirection: 'row',
paddingLeft: 10,
flexWrap: 'wrap'
}}
>
{
this.props.team.map(
(v, i) => {
if(v.league.acronym === 'NFL'){
return(
<Check
key={i}
checked={ /*this.props.checkedLeagues.includes(v.league.acronym) ?*/ this.state.checked[i] /*: false*/ }
index={i}
teamObject={v}
value={v.team_name}
changeCheck={this.changeCheck}
/>
)
}
}
)
}
</View>
}
<View>
<Text
style={{
fontFamily: 'Helvetica',
fontSize: 13,
paddingLeft: 5,
paddingBottom: 5
}}
onPress={()=> this.changeTeamSelect(1)}
>
NBA TEAM SELECT
</Text>
</View>
{
this.state.accordionStatus[1] === false ? null :
<View
style={{
flexDirection: 'row',
paddingLeft: 10,
flexWrap: 'wrap'
}}
>
{
this.props.team.map(
(v, i) => {
if(v.league.acronym === 'NBA'){
return(
<Check
key={i}
checked={ /*this.props.checkedLeagues.includes(v.league.acronym) ?*/ this.state.checked[i] /*: false*/ }
index={i}
teamObject={v}
value={v.team_name}
changeCheck={this.changeCheck}
/>
)
}
}
)
}
</View>
}
<View>
<Text
style={{
fontFamily: 'Helvetica',
fontSize: 13,
paddingLeft: 5,
paddingBottom: 5
}}
onPress={()=> this.changeTeamSelect(2)}
>
MLB TEAM SELECT
</Text>
</View>
{
this.state.accordionStatus[2] === false ? null :
<View
style={{
flexDirection: 'row',
paddingLeft: 10,
flexWrap: 'wrap'
}}
>
{
this.props.team.map(
(v, i) => {
if(v.league.acronym === 'MLB'){
return(
<Check
key={i}
checked={ /*this.props.checkedLeagues.includes(v.league.acronym) ?*/ this.state.checked[i] /*: false */}
index={i}
teamObject={v}
value={v.team_name}
changeCheck={this.changeCheck}
/>
)
}
}
)
}
</View>
}
</View>
)
}
}
function mapStateToProps(state) {
return {
league: state.league.league,
team: state.team.team,
checkedLeagues: state.league.checkedLeagues,
checkedTeams: state.league.checkedTeams,
queryTeams: state.league.queryTeams
}
}
export default connect(mapStateToProps, { loadCards, changeLeagues })(TeamSelect)
需要注意的是,我使用redux来更新状态,将其放入存储中,然后在再次装入组件时使用它。有趣的是,this.state.checkedLeagues可以像在第一个组件中那样保留状态,但是this.state.checkedTeams不能在第二个组件中保留其状态。有什么想法吗?
编辑:
这是我的LeagueReducer:
let defaultState = {
league: null,
checkedLeagues: null,
checkedTeams: null,
queryTeams: null,
teamObject: null
}
export function LeagueReducer(state = defaultState, action){
if(action.type === "CHANGE_LEAGUES") {
return {
...state,
league: action.league,
checkedLeagues: action.checkedLeagues,
checkedTeams: action.checkedTeams,
queryTeams: action.queryTeams,
teamObject: action.teamObject
}
} else {
return state
}
}
答案 0 :(得分:0)
看起来您可能未正确更新Redux存储。切记不要使用像push
这样使数组变异的数组函数。您需要使用concat
之类的函数来返回新数组。