首页 > 解决方案 > 禁用模式并不总是通过 setState 起作用

问题描述

我有两个模态:

看法:

<Modal visible={this.state.modal} replay={this.gameReplay} close={this.gameStop} />
<LoseModal visible={this.state.modalClose} replay={this.gameReplay} close={this.gameStop} />

函数gameReplay()

gameReplay = () => {
    const level = this.props.navigation.state.params.level
    this.setState({ modalClose: false, modal: false })       
    this.props.navigation.push('play', { level: level })               
}

在这两种模式中,函数的调用方式相同

一切正常<LoseModal>。Visible 设置为 false 并且模态消失

问题出在<Modal>. 不工作。它不会返回任何错误并且模态不会消失

可能是什么问题呢?也许 setState 不能正常工作,但如果是这样,为什么?

编辑:

const { width, height } = Dimensions.get("window");
export default class playScreen extends Component {
    constructor(props) {
        super(props)
        this.state = {
            timer: 3, 
            gameStart: 0,
            gameStop: false, 
            wasteContainer: [], 
            wasteText: '', 
            win: 0, 
            loss: 0, 
            modal: false, 
            levelSetting: [], 
            onlineColor: {
                color: "#fff"
            }, 
            colorCounter: 0, 
            modalClose: false, 
            objectArray: [],
            mili:0
        }
    }

    componentDidMount() {
        this.onLoadHandler()
        this.getwasteText()
        this.getCategories()
    }

    shouldComponentUpdate(){
        if(this.state.mili !== 0)return false
        else {return true }
    }


    onLoadHandler = () => {
        const Timer = setInterval(() => {
            this.setState({ timer: this.state.timer - 1 })
            if (this.state.timer <= 0) {
                clearInterval(Timer)
                this.gameStart()
            }
        }, 1000)
    }

    gameStop = () => {
        this.setState({ gameStop: true })
        setTimeout(() => {
            this.props.navigation.navigate('home')
            console.log('hey im working')
        }, 1000)
    }

    gameReplay = () => {
        const level = this.props.navigation.state.params.level
        this.setState({ modalClose: false, modal: false })       
        this.props.navigation.push('play', { level: level })               
    }

    gameStart = () => {
        const level = this.props.navigation.state.params.level

        const Timer = setInterval(() => {
            const { objectArray, win, colorCounter, wasteContainer, gameStop, gameStart } = this.state
            this.setState({ gameStart: gameStart + 1, colorCounter: colorCounter + 1 })
            if (level === 'level1' ? colorCounter >=40 : colorCounter >= 90) {
                const colors = wasteContainer[objectArray[win].category_uid].color !== '' && wasteContainer[objectArray[win].category_uid].color !== null && wasteContainer[objectArray[win].category_uid].color !== undefined ? wasteContainer[objectArray[win].category_uid].color : '#fff'

                const updateColor =
                {
                    color: colors
                }
                this.setState({ onlineColor: updateColor })

            }
            if (objectArray.length !== 0 && win >= objectArray.length) {
                this.setState({ gameStop: true, modal: true })
                clearInterval(Timer)
                // this.miliSecondHandler()

            }
            else if (objectArray.length === 0) {
                clearInterval(Timer)
                this.setState({ gameStart: 0 })
            }
            if (gameStop) {
                clearInterval(Timer)
                // this.miliSecondHandler()
                console.log('hey im working game stop')
            }
        }, 100)

    }

    gameHandler = async (arg) => {
        const { objectArray, win, gameStart } = this.state
        if (objectArray.length > win && gameStart > 0) {
            const wasteId = objectArray && objectArray[win] && objectArray[win].id ? objectArray[win].id : undefined

            if (objectArray[win].category_uid === arg) {
                var setObj = objectArray[win];
                setObj.good_answer++;
               if(wasteId) await firebase.database().ref(`wastes/${wasteId}`).set(setObj);
                this.setState(
                    {
                        win: win + 1, colorCounter: 0,

                        onlineColor: {
                            color: "#fff"
                        }
                    })
            }
            else {
                this.setState({ gameStop: true, modalClose: true })
                // this.miliSecondHandler()
                let setObj = objectArray[win];
                setObj.wrong_answer++;
                if(wasteId) await firebase.database().ref(`wastes/${wasteId}`).set(setObj);
            }
        }

    }

    getCategories = async () => {
        const data = await firebase.database().ref('categories');
        await data.once('value', (snapshot) => {
            this.setState({ wasteContainer: snapshot.val() })
        })
    };

    getwasteText = async () => {
        const data = await firebase.database().ref('wastes');
        await data.once('value', (snapshot) => {
            this.setState({ wasteText: Object.values(snapshot.val()) });
            this.getLevel()
        })
    };

    getLevel = async () => {
        const data = await firebase.database().ref(`level/${this.props.navigation.state.params.level}`);
        await data.once('value', (snapshot) => {
            this.setState({ levelSetting: snapshot.val() })
            this.setLevel()
        })
    };


    setLevel = () => {
        const level = this.state.levelSetting
        const uids = ['AGHJgv7GFYKYUG', 'q23rfhgbrYKYUG', 'njyhtd6y7GFYKYUG', 'AgfdsggagGFYKYUG', '8ikr6t7dsgYKYUG'];
        for (let i = 0; i < uids.length; i++) {

            let s = this.state.wasteText.filter(
                // x => x.category_uid == uids[i]
                x => x.category_uid == uids[i] && x.level_uid === this.props.navigation.state.params.level
            )
            let shuffleArr = this.shuffleArray(s)
            let res = this.sorting(shuffleArr, level.settings[i])
            this.setState({ objectArray: [...this.state.objectArray, res.flat().flat()].flat() })
            let shuffleArr1 = this.shuffleArray(this.state.objectArray)

            this.setState({ objectArray: shuffleArr1 })

        }


    }

    shuffleArray = (arr) => {
        for (let i = arr.length - 1; i > 0; i--) {
            let j = Math.floor(Math.random() * (i + 1));
            let temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        return arr
    }

    sorting = (array, limit) => {
        const arr = [];
        arr.push(array.splice(0, limit));
        return arr
    }

    miliSecondHandler = async (sec) => {
         if(this.state.modal&&sec&&sec.second&&sec.mili){
            await this.setState({mili:`${sec.second},${sec.mili}`})
        }


    }



    render() {
        const { win, timer, gameStart, onlineColor, objectArray } = this.state
        const text = objectArray && objectArray[win] && objectArray[win].value !== null ? objectArray[win].value : ''
        const categoryUid = objectArray && objectArray[win] && objectArray[win].value !== null ? objectArray[win].category_uid : ''
        const flag = this.state.modal?this.state.modal:this.state.gameStop
        return (
            <SafeAreaView style={styles.safeAreaView}>
                <StatusBar backgroundColor="#104C80" barStyle="light-content" />
                <View style={styles.container}>
                    <TouchableOpacity onPress={() => this.gameStop('back')} style={styles.closeBtn}><Image source={require('../assets/close.png')} style={styles.closeBtnImg} resizeMode="contain" /></TouchableOpacity>
                    <View style={styles.topContainer}>
                        <ImageBackground source={require('../assets/bgimage.png')} style={styles.bgImg} resizeMode='contain'>
                            <Text style={styles.topText}>W worku pozostało:</Text>
                            <Text style={styles.totalItem}>{objectArray.length - win}</Text>
                        </ImageBackground>
                    </View>
                    <View style={styles.timerContainer}>

                        {timer === 0 && objectArray.length ? <Seconds stop={flag} handler={this.miliSecondHandler} styles={styles.secondsLeft}  />:null}
                        <Text style={styles.timerUnit}>{gameStart > 0 ? 'sekund' : ''}</Text>
                    </View>
                    <View style={styles.desContainer}>
                        {timer !== 0 ? <Text style={styles.timerDescribe}>Masz tylko jedną szansę!</Text> : <Text></Text>}    
                        {timer === 0 ? <Text style={[styles.questionText, onlineColor]}>{text}</Text>
                            : <Text style={styles.timer}>{timer}</Text>}
                    </View>
                    <View style={styles.wasteContainer}>
                        <Text style={styles.selectWaste}>Wrzucam do:</Text>
                        <View style={{ alignItems: "center", flexDirection: "row" }}>
                            <BinImage onPress={() => this.gameHandler('AGHJgv7GFYKYUG')} source={bin1} text='PAPIER' />
                            <BinImage onPress={() => this.gameHandler('q23rfhgbrYKYUG')} source={bin2} text='METAL/PLASTIK' />
                        </View>
                        <View style={{ alignItems: "center", flexDirection: "row" }}>
                            <BinImage onPress={() => this.gameHandler('njyhtd6y7GFYKYUG')} source={bin3} text='SZKŁO' />
                            <BinImage onPress={() => this.gameHandler('AgfdsggagGFYKYUG')} source={bin4} text='BIO' />
                            <BinImage onPress={() => this.gameHandler('8ikr6t7dsgYKYUG')} source={bin5} text='RESZTKOWE' />
                        </View>
                    </View>
                    <Modal visible={this.state.modal} seconds={this.state.mili} total={objectArray.length} score={win} replay={this.gameReplay} close={this.gameStop} />
                    <LoseModal visible={this.state.modalClose} categoryUid={categoryUid} wasteText={text} seconds={this.state.mili} total={objectArray.length} score={win} replay={this.gameReplay} close={this.gameStop} />

                </View>
            </SafeAreaView>
        )
    }
}

标签: javascriptreact-native

解决方案


推荐阅读