onPress in按钮提供状态转换错误

时间:2017-05-29 13:46:47

标签: reactjs react-native react-native-android

尝试运行删除功能时会出错:

  

警告:在现有状态转换期间无法更新(例如   在render或其他组件的构造函数中)。渲染方法   应该是道具和国家的纯粹功能;构造函数的副作用   是一种反模式,但可以移到componentWillMount

这是代码:

class registrationHome extends Component {

    constructor(props){
        super(props);

        this.state = {
            name: '',
            city: '',
            area: '',
            lat: '',
            lng: '',
            productName: '',
            products: []
        }

        this.getCoordinates = this.getCoordinates.bind(this);
        this.addProduct = this.addProduct.bind(this);
    }


    getCoordinates(){

    }

    addProduct(){
        var productsArray = this.state.products.slice();
        productsArray.push(this.state.productName);

        console.log(productsArray);
        this.setState({
            productName: '',
            products: productsArray
        });
        // console.log(this.state.products);
    }
    // remove function running recursively till stacksize exceeded
    removeProduct(index){
        var productsArray = this.state.products.splice(index,1);

        console.log(productsArray);
        this.setState({         
            products: productsArray
        });
    }

    test() {
        console.log('hey');
    }

    render() {
        // console.log(this.state.name);

        var products = this.state.products.map((product,i) => (
                            <View key={i}>
                                <Text >{product}</Text>
                                <Button
                                    title="remove"
                                    onPress={this.removeProduct(i)}
                                />
                            </View>
                        ));
        return(
            <View>              
                <TextInput
                    placeholder="Business Name"
                    onChangeText={ name => this.setState({ name })}                 
                />              
                <TextInput
                    placeholder="City Name"
                    onChangeText={ city => this.setState({ city })}                 
                />
                <TextInput
                    placeholder="Area Name"
                    onChangeText={ area => this.setState({ area })}                 
                />
                <View>
                    <Text>Enter products to save</Text>
                    <TextInput
                        placeholder="Enter product name"
                        onChangeText={ productName => this.setState({productName})}
                        defaultValue={this.state.productName}
                    />
                    <Button
                        title="Add Product"
                        onPress={this.addProduct}
                    />
                    <ScrollView style={{height: 70, marginVertical: 5}}>
                        <Text>Products Entered</Text>
                        {products}
                    </ScrollView>               
                </View>

                <View>
                    <Button
                        title="Get Coordinates"
                        onPress={this.getCoordinates}                   
                    />
                    <View style={styles.coordContainer}>
                        <Text>Lat: {this.state.lat}</Text>
                        <Text>Lng: {this.state.lng}</Text>                      
                    </View>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    coordContainer: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        borderWidth: 3,
    },


})

为什么会出现此错误以及如何在不使用listview的情况下更正错误。

你能详细说明上述情况发生了什么,以及为什么removeProduct()被无限调用,直到errorstack溢出。

1 个答案:

答案 0 :(得分:2)

在你的onPress中你需要传递一个像这样的函数

<Button
  title="remove"
  onPress={()=>this.removeProduct(i)}
 />

就像你在其他情况下这样做。

您要传递的是回调函数。当您使用带有括号(如myFunc())的函数名时,您可以立即调用该函数。这就是onPress={this.removeProduct(i)}基本上说&#34;评估this.removeProduct(i)并将结果用作回调的原因。这意味着您的removeProduct(i)函数在渲染期间运行,而不是在执行onPress操作时运行。你想要的是一个像()=>this.removeProduct(i)这样的函数声明。

然后错误是由于您在setState期间在removeProduct函数中调用了render方法。 React禁止在渲染期间调用setState