【问题标题】:onPress function with parameters runs creates loop带参数的 onPress 函数运行创建循环
【发布时间】:2017-02-10 15:42:46
【问题描述】:

我有这个组件,它有一个简单的按钮,当我按下按钮时,一个新的 Meta 应该被添加到显示中

Metas.js

import React, { Component } from 'react';
import { View, Text } from 'react-native';
import Meta from './Meta';
import Button from './Button';

class Metas extends Component {
    componentWillMount() {
        this.setState({
            metas: this.props.data,
        });
    }

    addMeta = (newMeta) => {
        console.log('Adding new meta');
        /*this.props.navigator.push({
            id: 'Test'
        });*/
        const metas = this.state.metas;
        metas.push(newMeta);
        this.setState({ metas });
        console.log(`Metas: ${metas}`);
    }

    renderData = () => {
        console.log('rendering metas data');
        return this.state.metas.map(meta => <Meta key={Math.random()} name={meta} />);
    }

    render() {
        return (
            <View>
                { this.renderData() }
                <View>
                    <Text>{this.state.metas.length} Metas</Text>
                    <Button
                        text='+'
                        color='#8783FF'
                        fontColor='white'
                        size='50'
                        fontSize='25'
                        onPress={this.addMeta('New Meta')}
                    />
                </View>
            </View>
        );
    }
}

export default Metas;

addMeta 函数的参数将来会由用户插入,但我目前只是测试重新渲染的工作原理

问题是,如果我不通过函数传递参数,并在 addMeta 中定义一个变量,它会完美运行(这样做是为了测试方法是否被绑定),但如果我按照上面显示的那样做,它会在onPress 属性甚至没有我点击它,导致我的应用程序崩溃

Button.js

import React, { Component } from 'react';
import { View, Text, TouchableNativeFeedback } from 'react-native';

class Button extends Component {
    render() {
        const { buttonStyle, centerHorizontally, textStyle } = styles;
        const { text, onButtonPress } = this.props;

        return (
            <TouchableNativeFeedback onPress={onButtonPress}>
                <View style={buttonStyle}>
                    <View style={centerHorizontally}>
                        <Text style={textStyle}>{text}</Text>
                    </View>
                </View>
            </TouchableNativeFeedback>
        );
    }
}

const styles = {
    buttonStyle: {
        borderRadius: 100,
        justifyContent: 'space-around',
        height: parseInt(this.props.size, 10),
        width: parseInt(this.props.size, 10),
        backgroundColor: this.props.color
    },
    /*TODO: use text align center instaed*/
    centerHorizontally: {
        flexDirection: 'row',
        justifyContent: 'space-around'
    },
    textStyle: {
        fontWeight: 'bold',
        fontSize: parseInt(this.props.fontSize, 10),
        lineHeight: parseInt(this.props.fontSize, 10)
            + Math.floor(parseInt(this.props.fontSize, 10) / 10) + 1,
        color: this.props.fontColor
    }
};

export default Button;

【问题讨论】:

    标签: javascript reactjs react-native ecmascript-6


    【解决方案1】:

    我看到你在渲染组件时正在执行addMeta。我不知道这是否是故意的,但它会导致在您按下按钮之前添加New Meta

    而不是像这里那样执行函数:

    onPress={this.addMeta('New Meta')}
    

    试试这样的:

    onPress={() =&gt; {this.addMeta('New Meta')}}

    【讨论】:

    • addMeta 是如何执行的?因为它是一个 onPress 属性,它不应该只在我按下它时运行吗?作为一个菜鸟问题,为什么你的建议会奏效?在我看来是在另一个箭头函数中调用箭头函数
    • onPress={this.addMeta('New Meta')} 将在每次渲染时调用。当您执行onPress={this.addMeta}时,它只会在按下时调用该函数,但由于您要传递参数,您可以创建一个仅在按下时调用的匿名函数onPress={() =&gt; this.addMeta('New Meta')}
    【解决方案2】:

    当您添加大括号时,您正在 调用 this.addMeta

    <Button 
      text='+' color='#8783FF' 
      fontColor='white' size='50' 
      fontSize='25' 
      onPress={this.addMeta('New Meta')}
    <!-- These braces -----^----------^        
          cause the function to execute         
    -->
    />
    

    解决方案:

    删除大括号并确保当您在 &lt;Button&gt; 组件中调用 addMeta 的向下传递方法时,您此时会传入相关参数:

    <Button 
      text='+' color='#8783FF' 
      fontColor='white' size='50' 
      fontSize='25' 
      onPress={this.addMeta.bind(this)}
      <!--
        ensure you bind this method to
         local component scope
         (You can do this in the constructor instead
         if here if you like)
      -->
    />
    

    Button.js

    class Button extends Component {
      handleOnPress(){
        this.props.onPress(parameterToPass);
      }
    
      render() {
        const {buttonStyle, centerHorizontally, textStyle } = styles; 
        const { text } = this.props; 
    
        return (
          <TouchableNativeFeedback 
              onPress={this.handleOnPress}> 
            <View style={buttonStyle}> 
              <View style={centerHorizontally}> 
                <Text style={textStyle}>{text}</Text> 
              </View> 
            </View> 
          </TouchableNativeFeedback> 
        ); 
      } 
    }
    

    【讨论】:

      【解决方案3】:

      我不知道为什么,但这应该可以;

      <Button
        text='+'
        color='#8783FF'
        fontColor='white'
        size='50'
        fontSize='25'
        onPress={this.addMeta.bind(null, 'New Meta')}
      />

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-21
        • 1970-01-01
        • 1970-01-01
        • 2014-12-12
        • 1970-01-01
        • 2018-11-16
        相关资源
        最近更新 更多