我无法将参数传递给 React Native 的 props 内的函数
I can't pass arguments to a function inside props on React Native
我是 React Native 开发的新手,我很难理解为什么我传递给像 <TouchableHighlight onPress={props.executeFunction(props.label)}>
这样的函数的参数是 SyntheticBaseEvent,而不是 props.label 本身
在 App.js:37 console.log 上显示 SyntheticBaseEvent {_reactName: 'onClick', _targetInst: null, type: 'click', nativeEvent: PointerEvent, target:
我是否丢失了对原始函数的引用?
App.js:
import { StyleSheet, Text, View } from 'react-native';
import React, { Component } from 'react'
import Calculator from './Calculator';
import { LinearGradient } from 'expo-linear-gradient';
const initialState = {
displayValue: '0',
clearDisplay: false,
previousOperation: null,
operation: null,
values: [null, null],
currentPositionOnValues: 0,
originalValue: 0
}
class App extends Component {
constructor(props) {
super(props);
this.state = { ...initialState }
this.clear = this.clear.bind(this);
this.addDigit = this.addDigit.bind(this);
}
clear() {
this.setState({ ...initialState });
}
addDigit(digit) {
console.log(digit)
if (digit === "." && this.state.displayValue.includes('.')) {
// Prevent double decimals
return
}
const clearDisplay = this.state.displayValue === '0' || this.state.clearDisplay
/*
Boolean value saying if it's necessary to clear the display
True if the currentValue display value is 0 or the variable this.state.clearDisplay is set to true
*/
const currentValue = clearDisplay ? '' : this.state.displayValue
/*
currentValue shows the 'cleared' value or the display value
*/
const displayValue = currentValue + digit
this.setState({ displayValue: displayValue, clearDisplay: false })
if (digit !== '.') {
const i = this.state.currentPositionOnValues
const newValue = parseFloat(displayValue)
const values = [...this.state.values]
values[i] = newValue
this.setState({ values: values })
}
}
render() {
return (
<View style={styles.container}>
<LinearGradient
colors={['#4b6cb7', '#182848']}
style={styles.background}
start={[1, 1]} end={[0, 0]}
>
</LinearGradient>
<Text style={styles.head}>Calculator</Text>
<Calculator
addDigit={() => this.addDigit}
clear={() => this.clear}
setOperation={() => this.setOperation}
displayValue = {this.state.displayValue}
/>
</View>
);
}
}
export default App;
Calculator.js
import React from 'react';
import { View } from 'react-native';
import Interface from './Interface';
const Calculator = (props) => {
return (
<View>
<Interface
addDigit={props.addDigit}
clear={props.clear}
displayValue={props.displayValue}
setOperation={props.setOperation}
/>
</View>
);
}
export default Calculator;
Interface.js
import React from 'react';
import { View, StyleSheet, FlatList, Text } from 'react-native';
import Button from './Button';
import Display from './Display';
const Interface = (props) => {
return (
<View style={style.container}>
<Display value={props.displayValue} />
<Button label="AC" executeFunction={props.clear} triple />
<Button label="/" executeFunction={props.setOperation} operation />
<Button label="7" executeFunction={props.addDigit} />
<Button label="8" executeFunction={props.addDigit} />
<Button label="9" executeFunction={props.addDigit} />
<Button label="*" executeFunction={props.setOperation} operation />
<Button label="4" executeFunction={props.addDigit} />
<Button label="5" executeFunction={props.addDigit} />
<Button label="6" executeFunction={props.addDigit} />
<Button label="-" executeFunction={props.setOperation} operation />
<Button label="1" executeFunction={props.addDigit} />
<Button label="2" executeFunction={props.addDigit} />
<Button label="3" executeFunction={props.addDigit} />
<Button label="+" executeFunction={props.setOperation} operation />
<Button label="0" executeFunction={props.addDigit} double />
<Button label="." executeFunction={props.addDigit} />
<Button label="=" executeFunction={props.setOperation} operation />
</View>
);
}
const style = StyleSheet.create({
container: {
width: 400,
borderRadius: 5,
overflow: 'hidden',
position: 'relative',
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
}
})
export default Interface
Button.js
import React from "react";
import { View, StyleSheet, Text, TouchableHighlight } from "react-native";
const Button = (props) => {
let classes = 'button '
classes += props.operation ? 'operation' : ''
classes += props.double ? 'double' : ''
classes += props.triple ? 'triple' : ''
if (props.operation) {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)}>
<View style={[style.button, style.operation]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else if (props.double) {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)}>
<View style={[style.button, style.double]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else if (props.triple) {
return (
<TouchableHighlight onPress={props.executeFunction()}>
<View style={[style.button, style.triple]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)} activeOpacity={0.8}>
<View style={[style.button]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
}
}
const style = StyleSheet.create({
button: {
width: 100,
height: 100,
fontSize: 30,
backgroundColor: '#f0f0f0',
outline: 'none',
textAlign: 'center',
justifyContent: 'space-evenly',
borderColor: '#888',
borderWidth: 1,
borderStyle: 'solid',
},
double: {
width: 200,
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
}
})
export default Button
更新了您的代码:https://snack.expo.dev/qw9iqqVxs
App.JS
import { StyleSheet, Text, View } from 'react-native';
import React, { Component } from 'react';
import Calculator from './Calculator';
import { LinearGradient } from 'expo-linear-gradient';
const initialState = {
displayValue: 0,
clearDisplay: false,
previousOperation: null,
operation: null,
values: [null, null],
currentPositionOnValues: 0,
originalValue: 0,
};
class App extends Component {
constructor(props) {
super(props);
this.state = { ...initialState };
this.clear = this.clear.bind(this);
this.addDigit = this.addDigit.bind(this);
}
clear() {
this.setState({ ...initialState });
};
addDigit(digit){
if (digit === '.' && this.state.displayValue.includes('.')) {
// Prevent double decimals
return;
}
const clearDisplay =
this.state.displayValue === '0' || this.state.clearDisplay;
/*
Boolean value saying if it's necessary to clear the display
True if the currentValue display value is 0 or the variable this.state.clearDisplay is set to true
*/
const currentValue = clearDisplay ? '' : this.state.displayValue;
/*
currentValue shows the 'cleared' value or the display value
*/
const displayValue = currentValue + digit;
this.setState({ displayValue: displayValue, clearDisplay: false })
if (digit !== '.') {
const i = this.state.currentPositionOnValues;
const newValue = parseFloat(displayValue)
const values = [...this.state.values];
values[i] = newValue;
this.setState({ values: values });
}
};
render() {
return (
<View style={styles.container}>
<LinearGradient
colors={['#4b6cb7', '#182848']}
style={styles.background}
start={[1, 1]}
end={[0, 0]}></LinearGradient>
<Text style={styles.head}>Calculator</Text>
<Text style={styles.head}>
{JSON.stringify(this.state.displayValue)}
</Text>
<Calculator
addDigit={(digit) => {
this.addDigit(digit);
}}
clear={(value) => {
this.clear(value)
}}
setOperation={this.setOperation}
displayValue={this.state.displayValue}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
background: {
background: 'red',
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
},
});
export default App;
Button.JS
import React from "react";
import { View, StyleSheet, Text, TouchableHighlight } from "react-native";
const Button = ({operation, double, triple, executeFunction, label}) => {
let classes = 'button '
classes += operation ? 'operation' : ''
classes += double ? 'double' : ''
classes += triple ? 'triple' : ''
if (operation) {
return (
<TouchableHighlight onPress={()=>executeFunction(label)}>
<View style={[style.button, style.operation]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else if (double) {
return (
<TouchableHighlight onPress={()=>executeFunction(label)}>
<View style={[style.button, style.double]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else if (triple) {
return (
<TouchableHighlight onPress={()=>executeFunction()}>
<View style={[style.button, style.triple]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else {
return (
<TouchableHighlight onPress={()=>executeFunction(label)} activeOpacity={0.8}>
<View style={[style.button]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
}
}
const style = StyleSheet.create({
button: {
width: 100,
height: 100,
fontSize: 30,
backgroundColor: '#f0f0f0',
outline: 'none',
textAlign: 'center',
justifyContent: 'space-evenly',
borderColor: '#888',
borderWidth: 1,
borderStyle: 'solid',
},
double: {
width: 200,
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
}
})
export default Button
计算器
import React from 'react';
import { View } from 'react-native';
import Interface from './Interface';
const Calculator = ({addDigit, clear, displayValue, setOperation}) => {
return (
<View>
<Interface
addDigit={addDigit}
clear={clear}
displayValue={displayValue}
setOperation={setOperation}
/>
</View>
);
}
export default Calculator;
Interface.JS
import React from 'react';
import { View, StyleSheet, FlatList, Text } from 'react-native';
import Button from './Button';
const Interface = ({clear, addDigit, setOperation}) => {
return (
<View style={style.container}>
<Button label="AC" executeFunction={clear} triple />
<Button label="/" executeFunction={setOperation} operation />
<Button label="7" executeFunction={addDigit} />
<Button label="8" executeFunction={addDigit} />
<Button label="9" executeFunction={addDigit} />
<Button label="*" executeFunction={setOperation} operation />
<Button label="4" executeFunction={addDigit} />
<Button label="5" executeFunction={addDigit} />
<Button label="6" executeFunction={addDigit} />
<Button label="-" executeFunction={setOperation} operation />
<Button label="1" executeFunction={addDigit} />
<Button label="2" executeFunction={addDigit} />
<Button label="3" executeFunction={addDigit} />
<Button label="+" executeFunction={setOperation} operation />
<Button label="0" executeFunction={addDigit} double />
<Button label="." executeFunction={addDigit} />
<Button label="=" executeFunction={setOperation} operation />
</View>
);
}
const style = StyleSheet.create({
container: {
width: 400,
borderRadius: 5,
overflow: 'hidden',
position: 'relative',
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
}
})
export default Interface
发生了什么事?
当前,当组件加载时,您的代码将执行 props.executeFunction(props.label)
一次 。
这是因为函数在计算时立即被调用:
// directly invokes `props.executeFunction` with `props.label` because of brackets `()`
onPress={props.executeFunction(props.label)}
因为你的函数 returns undefined
,这是随后传递给 onPress
属性的内容。
有什么解决办法?
如果你想传递 props.label
那么你可以通过匿名函数传递:
onPress={() => props.executeFunction(props.label)}
onPress
属性将匿名函数附加到事件。当事件被触发时,将调用该函数,该函数将依次调用 props.executeFunction
并根据需要传递 props.label
。
SyntheticEvent
onPress
函数在调用处理程序时传递一个 SyntheticEvent
。我们可以通过在匿名函数中记录事件来看到这一点:
onPress={(event) => console.log(event)} // SyntheticEvent
因此,如果您将 props.executeFunction
作为直接参数传递给 onPress
道具,则此事件将被传递:
onPress={props.executeFunction} // passes the event as the argument to `props.executeFunction`
例子
调用内联
这会在计算表达式(一次)时执行该函数。 undefined
被返回并传递给 onClick
所以 onClick
处理程序没有被添加。
function App(props) {
function foo(bar) {
console.log(bar);
}
return (
<button onClick={foo("test")}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
通过匿名函数调用
向 onClick
处理程序传递匿名函数,该函数将在每次点击时执行。
如果您需要将参数传递给您的函数,这将很有用。
function App(props) {
function foo(bar) {
console.log(bar);
}
return (
<button onClick={() => foo("test")}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
将函数作为参数传递
事件被传递给函数。
如果您需要访问该事件,这将很有用。
function App(props) {
function foo(bar) {
console.log(bar); // this logs the event as the event is passed
}
return (
<button onClick={foo}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react-root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>
我是 React Native 开发的新手,我很难理解为什么我传递给像 <TouchableHighlight onPress={props.executeFunction(props.label)}>
这样的函数的参数是 SyntheticBaseEvent,而不是 props.label 本身
在 App.js:37 console.log 上显示 SyntheticBaseEvent {_reactName: 'onClick', _targetInst: null, type: 'click', nativeEvent: PointerEvent, target:
我是否丢失了对原始函数的引用?
App.js:
import { StyleSheet, Text, View } from 'react-native';
import React, { Component } from 'react'
import Calculator from './Calculator';
import { LinearGradient } from 'expo-linear-gradient';
const initialState = {
displayValue: '0',
clearDisplay: false,
previousOperation: null,
operation: null,
values: [null, null],
currentPositionOnValues: 0,
originalValue: 0
}
class App extends Component {
constructor(props) {
super(props);
this.state = { ...initialState }
this.clear = this.clear.bind(this);
this.addDigit = this.addDigit.bind(this);
}
clear() {
this.setState({ ...initialState });
}
addDigit(digit) {
console.log(digit)
if (digit === "." && this.state.displayValue.includes('.')) {
// Prevent double decimals
return
}
const clearDisplay = this.state.displayValue === '0' || this.state.clearDisplay
/*
Boolean value saying if it's necessary to clear the display
True if the currentValue display value is 0 or the variable this.state.clearDisplay is set to true
*/
const currentValue = clearDisplay ? '' : this.state.displayValue
/*
currentValue shows the 'cleared' value or the display value
*/
const displayValue = currentValue + digit
this.setState({ displayValue: displayValue, clearDisplay: false })
if (digit !== '.') {
const i = this.state.currentPositionOnValues
const newValue = parseFloat(displayValue)
const values = [...this.state.values]
values[i] = newValue
this.setState({ values: values })
}
}
render() {
return (
<View style={styles.container}>
<LinearGradient
colors={['#4b6cb7', '#182848']}
style={styles.background}
start={[1, 1]} end={[0, 0]}
>
</LinearGradient>
<Text style={styles.head}>Calculator</Text>
<Calculator
addDigit={() => this.addDigit}
clear={() => this.clear}
setOperation={() => this.setOperation}
displayValue = {this.state.displayValue}
/>
</View>
);
}
}
export default App;
Calculator.js
import React from 'react';
import { View } from 'react-native';
import Interface from './Interface';
const Calculator = (props) => {
return (
<View>
<Interface
addDigit={props.addDigit}
clear={props.clear}
displayValue={props.displayValue}
setOperation={props.setOperation}
/>
</View>
);
}
export default Calculator;
Interface.js
import React from 'react';
import { View, StyleSheet, FlatList, Text } from 'react-native';
import Button from './Button';
import Display from './Display';
const Interface = (props) => {
return (
<View style={style.container}>
<Display value={props.displayValue} />
<Button label="AC" executeFunction={props.clear} triple />
<Button label="/" executeFunction={props.setOperation} operation />
<Button label="7" executeFunction={props.addDigit} />
<Button label="8" executeFunction={props.addDigit} />
<Button label="9" executeFunction={props.addDigit} />
<Button label="*" executeFunction={props.setOperation} operation />
<Button label="4" executeFunction={props.addDigit} />
<Button label="5" executeFunction={props.addDigit} />
<Button label="6" executeFunction={props.addDigit} />
<Button label="-" executeFunction={props.setOperation} operation />
<Button label="1" executeFunction={props.addDigit} />
<Button label="2" executeFunction={props.addDigit} />
<Button label="3" executeFunction={props.addDigit} />
<Button label="+" executeFunction={props.setOperation} operation />
<Button label="0" executeFunction={props.addDigit} double />
<Button label="." executeFunction={props.addDigit} />
<Button label="=" executeFunction={props.setOperation} operation />
</View>
);
}
const style = StyleSheet.create({
container: {
width: 400,
borderRadius: 5,
overflow: 'hidden',
position: 'relative',
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
}
})
export default Interface
Button.js
import React from "react";
import { View, StyleSheet, Text, TouchableHighlight } from "react-native";
const Button = (props) => {
let classes = 'button '
classes += props.operation ? 'operation' : ''
classes += props.double ? 'double' : ''
classes += props.triple ? 'triple' : ''
if (props.operation) {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)}>
<View style={[style.button, style.operation]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else if (props.double) {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)}>
<View style={[style.button, style.double]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else if (props.triple) {
return (
<TouchableHighlight onPress={props.executeFunction()}>
<View style={[style.button, style.triple]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)} activeOpacity={0.8}>
<View style={[style.button]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
}
}
const style = StyleSheet.create({
button: {
width: 100,
height: 100,
fontSize: 30,
backgroundColor: '#f0f0f0',
outline: 'none',
textAlign: 'center',
justifyContent: 'space-evenly',
borderColor: '#888',
borderWidth: 1,
borderStyle: 'solid',
},
double: {
width: 200,
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
}
})
export default Button
更新了您的代码:https://snack.expo.dev/qw9iqqVxs
App.JS
import { StyleSheet, Text, View } from 'react-native';
import React, { Component } from 'react';
import Calculator from './Calculator';
import { LinearGradient } from 'expo-linear-gradient';
const initialState = {
displayValue: 0,
clearDisplay: false,
previousOperation: null,
operation: null,
values: [null, null],
currentPositionOnValues: 0,
originalValue: 0,
};
class App extends Component {
constructor(props) {
super(props);
this.state = { ...initialState };
this.clear = this.clear.bind(this);
this.addDigit = this.addDigit.bind(this);
}
clear() {
this.setState({ ...initialState });
};
addDigit(digit){
if (digit === '.' && this.state.displayValue.includes('.')) {
// Prevent double decimals
return;
}
const clearDisplay =
this.state.displayValue === '0' || this.state.clearDisplay;
/*
Boolean value saying if it's necessary to clear the display
True if the currentValue display value is 0 or the variable this.state.clearDisplay is set to true
*/
const currentValue = clearDisplay ? '' : this.state.displayValue;
/*
currentValue shows the 'cleared' value or the display value
*/
const displayValue = currentValue + digit;
this.setState({ displayValue: displayValue, clearDisplay: false })
if (digit !== '.') {
const i = this.state.currentPositionOnValues;
const newValue = parseFloat(displayValue)
const values = [...this.state.values];
values[i] = newValue;
this.setState({ values: values });
}
};
render() {
return (
<View style={styles.container}>
<LinearGradient
colors={['#4b6cb7', '#182848']}
style={styles.background}
start={[1, 1]}
end={[0, 0]}></LinearGradient>
<Text style={styles.head}>Calculator</Text>
<Text style={styles.head}>
{JSON.stringify(this.state.displayValue)}
</Text>
<Calculator
addDigit={(digit) => {
this.addDigit(digit);
}}
clear={(value) => {
this.clear(value)
}}
setOperation={this.setOperation}
displayValue={this.state.displayValue}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
background: {
background: 'red',
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
},
});
export default App;
Button.JS
import React from "react";
import { View, StyleSheet, Text, TouchableHighlight } from "react-native";
const Button = ({operation, double, triple, executeFunction, label}) => {
let classes = 'button '
classes += operation ? 'operation' : ''
classes += double ? 'double' : ''
classes += triple ? 'triple' : ''
if (operation) {
return (
<TouchableHighlight onPress={()=>executeFunction(label)}>
<View style={[style.button, style.operation]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else if (double) {
return (
<TouchableHighlight onPress={()=>executeFunction(label)}>
<View style={[style.button, style.double]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else if (triple) {
return (
<TouchableHighlight onPress={()=>executeFunction()}>
<View style={[style.button, style.triple]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else {
return (
<TouchableHighlight onPress={()=>executeFunction(label)} activeOpacity={0.8}>
<View style={[style.button]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
}
}
const style = StyleSheet.create({
button: {
width: 100,
height: 100,
fontSize: 30,
backgroundColor: '#f0f0f0',
outline: 'none',
textAlign: 'center',
justifyContent: 'space-evenly',
borderColor: '#888',
borderWidth: 1,
borderStyle: 'solid',
},
double: {
width: 200,
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
}
})
export default Button
计算器
import React from 'react';
import { View } from 'react-native';
import Interface from './Interface';
const Calculator = ({addDigit, clear, displayValue, setOperation}) => {
return (
<View>
<Interface
addDigit={addDigit}
clear={clear}
displayValue={displayValue}
setOperation={setOperation}
/>
</View>
);
}
export default Calculator;
Interface.JS
import React from 'react';
import { View, StyleSheet, FlatList, Text } from 'react-native';
import Button from './Button';
const Interface = ({clear, addDigit, setOperation}) => {
return (
<View style={style.container}>
<Button label="AC" executeFunction={clear} triple />
<Button label="/" executeFunction={setOperation} operation />
<Button label="7" executeFunction={addDigit} />
<Button label="8" executeFunction={addDigit} />
<Button label="9" executeFunction={addDigit} />
<Button label="*" executeFunction={setOperation} operation />
<Button label="4" executeFunction={addDigit} />
<Button label="5" executeFunction={addDigit} />
<Button label="6" executeFunction={addDigit} />
<Button label="-" executeFunction={setOperation} operation />
<Button label="1" executeFunction={addDigit} />
<Button label="2" executeFunction={addDigit} />
<Button label="3" executeFunction={addDigit} />
<Button label="+" executeFunction={setOperation} operation />
<Button label="0" executeFunction={addDigit} double />
<Button label="." executeFunction={addDigit} />
<Button label="=" executeFunction={setOperation} operation />
</View>
);
}
const style = StyleSheet.create({
container: {
width: 400,
borderRadius: 5,
overflow: 'hidden',
position: 'relative',
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
}
})
export default Interface
发生了什么事?
当前,当组件加载时,您的代码将执行 props.executeFunction(props.label)
一次 。
这是因为函数在计算时立即被调用:
// directly invokes `props.executeFunction` with `props.label` because of brackets `()`
onPress={props.executeFunction(props.label)}
因为你的函数 returns undefined
,这是随后传递给 onPress
属性的内容。
有什么解决办法?
如果你想传递 props.label
那么你可以通过匿名函数传递:
onPress={() => props.executeFunction(props.label)}
onPress
属性将匿名函数附加到事件。当事件被触发时,将调用该函数,该函数将依次调用 props.executeFunction
并根据需要传递 props.label
。
SyntheticEvent
onPress
函数在调用处理程序时传递一个 SyntheticEvent
。我们可以通过在匿名函数中记录事件来看到这一点:
onPress={(event) => console.log(event)} // SyntheticEvent
因此,如果您将 props.executeFunction
作为直接参数传递给 onPress
道具,则此事件将被传递:
onPress={props.executeFunction} // passes the event as the argument to `props.executeFunction`
例子
调用内联
这会在计算表达式(一次)时执行该函数。 undefined
被返回并传递给 onClick
所以 onClick
处理程序没有被添加。
function App(props) {
function foo(bar) {
console.log(bar);
}
return (
<button onClick={foo("test")}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
通过匿名函数调用
向 onClick
处理程序传递匿名函数,该函数将在每次点击时执行。
如果您需要将参数传递给您的函数,这将很有用。
function App(props) {
function foo(bar) {
console.log(bar);
}
return (
<button onClick={() => foo("test")}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
将函数作为参数传递
事件被传递给函数。
如果您需要访问该事件,这将很有用。
function App(props) {
function foo(bar) {
console.log(bar); // this logs the event as the event is passed
}
return (
<button onClick={foo}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react-root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>