无法通过道具更新子状态

时间:2020-02-06 16:19:35

标签: javascript reactjs react-native

当我通过prop发送它们时,子组件未更新textinput值。

我很确定问题出在componentDidUpdate中,但我不知道这是什么。

这些是复制步骤:

  1. 我在输入中手动编写
  2. 我从道具发送值
  3. 输入文字未更新
import React, { Component } from 'react';
import { View, Text, StyleSheet, TextInput, Clipboard, Button } from 'react-native';

export default class BotomQRScanner extends Component{
    constructor(props){
        super(props);
        this.state = {
            userField: this.props.user,
            userInitialized: this.props.userInitialized,
            passInitialized: this.props.passInitialized,
            passwordField: this.props.pass
        }
    }

    componentDidUpdate(previousProps) {
        if (previousProps.user !== this.props.user) {
            this.setState({ 
                userField: this.props.user, 
                passwordField: this.props.pass, 
                userInitialized: this.props.userInitialized, 
                passInitialized: this.props.passInitialized
            });
        }
    }

    handleUserChange = value => {
    this.setState({userField: value, userInitialized: true});
  }

    handlePasswordChange = value => {
    this.setState({passwordField: value, passInitialized: true});
  }

    render(){
        return (
            <View style={{height: '100%', width: '100%', alignItems: 'center', justifyContent: 'space-around'}}>

                <View style={{flexDirection: 'row', justifyContent: 'space-around', alignItems: 'center'}}>
                    <TextInput
                onChangeText={(value) => this.handleUserChange(value)}
                style={{textAlign: 'center', fontSize: 16, height: 50, width: 200}}
                autoCapitalize = 'none'
                autoCorrect={false}
                selectTextOnFocus={true}
                placeholder={'username'}
                selectionColor={'#428AF8'}
                value={this.state.userInitialized? this.state.userField : this.props.user}
              />
              <Button
              title="copy"
              onPress={() => {
              Clipboard.setString(this.state.userInitialized? this.state.userField : this.props.user)
            }}
            />
          </View>

          <View style={{flexDirection: 'row', justifyContent: 'space-around', alignItems: 'center'}}>
                    <TextInput
                onChangeText={(value) => this.handlePasswordChange(value)}
                style={{textAlign: 'center', fontSize: 16, height: 80, width: 200}}
                autoCapitalize = 'none'
                autoCorrect={false}
                selectTextOnFocus={true}
                placeholder={'password'}
                value={this.state.passInitialized? this.state.passwordField : this.props.pass}
              />
              <Button
              title="copy"
              onPress={() => {
              Clipboard.setString(this.state.passInitialized? this.state.passwordField : this.props.pass)
            }}
            />
          </View>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    logo: {
        width: 80,
        height: 26,
        resizeMode: 'contain',
    },
    container: {
        padding: 10,
        flexDirection: 'row',
    },
    right: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'flex-end',
    }
})

3 个答案:

答案 0 :(得分:1)

原因

根据官方文件here

避免将道具复制到状态中!这是一个常见的错误

constructor(props) {
 super(props);
 // Don't do this!
 this.state = { color: props.color };
}

仅当您有意忽略道具更新时才使用此模式

显然不是您的情况。

答案 1 :(得分:1)

constructor(props){
    super(props);
    this.state = {
        userField,
        userInitialized,
        passInitialized,
        passwordField,
    }
}

// where you can set your initial values from props..
componentWillMount() {
    const { user, pass, userInitialized, passInitialized } = this.props

    this.setState(prevState => ({
     ...prevState,
     userField: user, 
     passwordField: pass, 
     userInitialized: userInitialized, 
     passInitialized: passInitialized,
    }))
}

// where you can update props upon comparison..
componentWillReceiveProps(nextProps) {
 const { user, pass, userInitialized, passInitialized } = nextProps

  if (nextProps.user !== this.props.user) {
    this.setState(prevState => ({
     ...prevState,
     userField: user, 
     passwordField: pass, 
     userInitialized: userInitialized, 
     passInitialized: passInitialized,
    }))  
 }
}

答案 2 :(得分:0)

我之前也遇到过这种情况,我不知道它是否对您有用,请尝试检查。您正在比较的两个数据。也许是您没有通过道具或没有更新新道具的问题。