首页 > 解决方案 > 函数中多次状态设置

问题描述

我正在尝试通过使用更改状态,this.setSTate但应用程序挂起并且状态继续设置,直到应用程序崩溃,请问可能出了什么问题,我正在尝试在textbar函数中设置状态,状态的名称是attached。这是我下面的代码

type Props = {};
export default class NewNote extends Component<Props> {
    static navigationOptions = {
        header: null,
        drawerLockMode: 'locked-closed'
    };
    constructor(props) {
        super(props);
        this.state = {
            photoPermission: '',
            songs: [], 
            loaded: true,
            loading: false,
            new_Press: false,
            text: '',
            selection: [0,0],
            pressed: false,
            boldButton: false,
            underlineButton: false,
            italicButton: false,
            attached: ''
        };
        this.textBar = this.textBar.bind(this);
      }
      componentDidUpdate(){ 
        if(this.state.pressed){
          this.TextInput.focus();  
        }
    }
    textinputter(){
    this.setState({pressed: true});

    }
    textBar(){
        const B = (props) => <Text style={{fontWeight: 'bold'}}>{props.children}</Text>
        const {selection: [start, end], text, pressed, boldButton} = this.state
        const texted = text;
        if(texted){
        if((start || start == 0) && (boldButton) && end!= 0){
        const attacher = text.substring(0, start)+"{b}"
        +text.substring(start, end)+"{/b}"+text.substring(end, text.length);
        this.setState({attached: attacher},); // this state keeps on setting until the app crashes
        return(
        <Text style={styles.text}>{text.substring(0, start)}
        <B>{text.substring(start, end)}</B>
        {text.substring(end, text.length)}</Text>
        );
        }else{
            return(
                <Text style={styles.text}>{text}</Text>
            );
        } 
        }else{
        //     this.setState({pressed: false}); 
      return(
        <Text style={styles.placeholder}>Your Note...</Text>
      ); } } 
onSelectionChange = event => {
        const selection = event.nativeEvent.selection;
        this.setState({
          selection: [selection.start, selection.end]
        });
      };

    render() {
        const B = (props) => <Text style={{fontWeight: 'bold'}}>{props.children}</Text> 
        const I = (props) => <Text style={{fontStyle: 'italic'}}>{props.children}</Text> 
        const U = (props) => <Text style={{textDecorationLine: 'underline'}}>{props.children}</Text> 
        const {selection: [start, end], text, pressed} = this.state;
        const selected = text.substring(start, end); 
        return (
            <View style={{flex: 1, backgroundColor: '#DDDBC7', 
            flexDirection: 'column', }}>
            <View style={{flexDirection: 'row', backgroundColor: 'transparent',
            height: 20, width: (Dimensions.get('window').width)*(85.1/100),
            justifyContent: 'space-between', alignItems: 'center', alignSelf: 'center',
            marginTop: 52+StatusBar.currentHeight}}>
            <TouchableWithoutFeedback onPress={() => this.props.navigation.goBack()}>
            <View style={{width: 14, height: 20, 
            alignItems: 'center', justifyContent: 'center'}}>
            <Image resizeMode="contain"
            style={{width: 12, height: 20}}
            source={require('../back.png')}/>
            </View></TouchableWithoutFeedback>
            <Text style={{color: 'rgba(0, 0, 0, 0.3)', fontFamily: 'zsBold',
            fontSize: 16}}>
                Save
            </Text>
            <Text style={{color: 'black', fontFamily: 'zsBold',
            fontSize: 16}}>
                Add
            </Text>
            </View>
            <ScrollView contentContainerstyle={{
                            flexGrow: 1,
                            }} 
                                        showsHorizontalScrollIndicator={false}
                                        showsVerticalScrollIndicator={false}
                                        automaticallyAdjustContentInsets={false}
                                        directionalLockEnabled={true}
                                        bounces={false}
                                        scrollsToTop={false}>
             <TextInput    
       underlineColorAndroid={'transparent'}
       allowFontScaling={false}
       placeholder="The Title"
                  placeholderStyle={{fontFamily: 'ZillaSlab-Bold',
            fontSize: 16,}}
                  placeholderTextColor="rgba(0, 0, 0, 0.2)"
style={{
                      paddingLeft: 28,
                      width: (Dimensions.get('window').width),
                      backgroundColor: 'transparent',
                      fontSize: 16, color: 'black',
                      borderTopWidth: 2, borderBottomWidth: 2, borderColor: 'black', 
            marginTop: 100, flexDirection: 'row', alignItems: 'center', fontFamily: 'ZillaSlab-Bold',
                  }}/>  

        {pressed?
                  <TextInput    
       value={text} onSelectionChange={this.onSelectionChange} 
                   onChangeText={text => this.setState({text})}   
       underlineColorAndroid={'transparent'}
       placeholder="Your Note..."
       multiline={true}
       selectionColor={'yellow'}
       ref={(input) => { this.TextInput = input; }}
       onBlur={()=>this.setState({pressed: false})}
                  placeholderStyle={{fontSize: 15, fontFamily: 'zsMedium',}}
                  placeholderTextColor="rgba(0, 0, 0, 0.2)"
style={{
                      paddingLeft: 28,
                      paddingTop: 28,
                      paddingRight: 28,
                      width: '100%',
                      backgroundColor: 'transparent',
                      fontSize: 15, fontFamily: 'zsMedium', color: 'black',
                  }}/>:
                  <TouchableWithoutFeedback
                  onPress={()=>this.setState({pressed: true})}>
                  <View style={{paddingLeft: 28,
                      paddingTop: 28,
                      paddingRight: 28,
                      width: '100%',
                      backgroundColor: 'transparent', }}>
                  {this.textBar()}
                      </View></TouchableWithoutFeedback>}   

标签: reactjsreact-native

解决方案


很常见的错误:

使用setStatewithin render(by textBar()) 会导致重新渲染和下一次调用setState(和下一次render调用) - 无限循环。

setState在事件处理程序中使用,绝不在 [unconditional parts of] 中使用render


推荐阅读