简体   繁体   中英

React change state with setTimeOut calling setState again

New to react native. I want to use state to change a button colour (that I defined in a class component) on a certain condition. I used setTimeOut and setState and right now the button changes, but only once (from darkgreen to lightgreen). Tried using setInterval and it did the same. I want it to change from dark to light and back to dark again. But I can't seem to find a way to call setState again. Would like some help, please. Thanks a lot, here is the class component:

class Green extends Component {
     constructor(props){
         super(props)
         this.state={}
         this.state.custum={
            backgroundColor: 'darkgreen'
         }

         if (this.props.greenFlash){
            setTimeout(() => {
                this.setState( {
                    custum:{
                        backgroundColor: 'lightgreen'
                    }
                    })
            }, 1000);
        }
     }    
    render() {
        return (
            <View style={[styles.greenB, this.state.custum]}> 
            </View>
        );
      }
    }  
    var styles = StyleSheet.create({
        greenB:{
          padding: 5,
          height: 80,
          width: 80,  
          borderRadius:160,    

        },
    })
export default Green;

try this working example acc to your code expo link :

Code is :

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';

// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

class Green extends React.Component {
     constructor(props){
         super(props)
         this.state={
            backgroundColor: 'darkgreen'
         }

     }   

     componentDidMount() {
       setInterval(() => {
         if(this.state.backgroundColor == "darkgreen"){
           this.setState({backgroundColor:'red'})
         } else {
           this.setState({backgroundColor:'darkgreen'})
         }

     },1000)
     }
    render() {
        return (
            <View style={[styles.greenB,{backgroundColor:this.state.backgroundColor}]}> 
            </View>
        );
      }
    }  
    var styles = StyleSheet.create({
        greenB:{
          padding: 5,
          height: 80,
          width: 80,  
          borderRadius:160,    

        },
    })
export default Green;

I would do it like this:

constructor(props) {
     super(props)
     this.state={}
     this.state.custum={
        backgroundColor: 'darkgreen'
     }

     if (this.props.greenFlash){
        this.intervalId = setInterval(() => {
            this.setState(prevState => {
              const bgcolor = (prevState.custum.backgroundColor === 'lightgreen') ? 'darkgreen' : 'lightgreen';
              return {
                custum:{
                    backgroundColor: bgcolor
                 }
                }
            })
        }, 1000);
    }
 } 

A few things to note:

A) You're saving this.intervalId so you can call clearInterval(this.intervalId) in your componentWillUnmount . Otherwise your interval will keep on calling long after your component has been destroyed.

B) you may want to define your interval in componentDidMount instead of the constructor, as that's generally the standard when you're calling this.setState , because this.setState is not available until componentDidMount is called. However, because the first time it will be called is after 1 second, I'm not going to say it's a huge concern. Just standard practice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM