我在React Native中创建了一个简单的pomodoro应用程序,我遇到了从子组件调用方法的问题。在下面的代码中,我尝试调用的方法是reset
,我在父级中从resetTimer
调用。这不起作用,但不会产生错误;方法中的console.logging也不会产生任何结果。我按照文档中概述的here模型进行了操作。任何解决此问题的帮助都将不胜感激!
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
class Timer extends React.Component {
constructor(props) {
super(props)
this.state = {
minutes: 25,
seconds: 0,
pomodoro: props.pomodoro,
}
}
componentDidMount() {
this.interval = setInterval(this.decrement, 1000)
}
reset = () => {
this.setState(prevState => ({
minutes: (prevState.pomodoro ? 5 : 25),
seconds: 0,
}))
}
decrement = () => {
if ((this.state.minutes+this.state.seconds)===0){
this.setState(prevState => ({
pomodoro: !prevState.pomodoro,
minutes: (prevState.pomodoro ? 25 : 5),
}))
} else{
if (this.props.start){
if (this.state.seconds===0){
this.setState(prevState => ({
minutes: prevState.minutes - 1,
seconds: 59,
}))
} else{
this.setState(prevState => ({
seconds: prevState.seconds - 1
}))
}
}
}
}
render() {
return (
<Text style={styles.time}>
{("0"+this.state.minutes).slice(-2)}:
{("0"+this.state.seconds).slice(-2)}
{this.props.start}
</Text>
);
}
}
export default class App extends React.Component {
constructor (props) {
super(props)
this.state = {
start: false,
pomodoro: false,
buttonText: "Start"
}
}
toggleStart = () => this.setState(prevState => ({
start: !prevState.start,
buttonText: (prevState.start ? "Start" : "Stop")
}))
resetTimer = () => {
this.toggleStart()
this._timer.reset()
}
render() {
return (
<View style={styles.container}>
<Timer
start={this.state.start}
pomodoro={this.state.pomodoro}
reset={this.state.reset}
toggleStart={() => this.toggleStart}
ref={component => { this._timer = component; }}
/>
<View style={styles.buttonRow}>
<Button
title={this.state.buttonText}
onPress={this.toggleStart}>
</Button>
<Button
title="Reset"
onPress={this.resetTimer}>
Timer.resetTime
</Button>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
time: {
fontSize: 70,
color: 'tomato',
alignItems: 'center',
justifyContent: 'center',
},
buttonRow: {
flexDirection: 'row'
},
});
答案 0 :(得分:0)
通常,您不必在父级中调用子级函数。当您发现自己处于这种情况时,可能会使组件结构过于复杂。为什么不将重置按钮移动到Timer
组件?
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
class Timer extends React.Component {
constructor(props) {
super(props)
this.state = {
minutes: 25,
seconds: 0,
pomodoro: props.pomodoro,
}
}
componentDidMount() {
this.interval = setInterval(this.decrement, 1000)
}
reset = () => this.setState(prevState({
minutes: (prevState.pomodoro ? 5 : 25),
seconds: 0,
}))
decrement = () => {
if ((this.state.minutes+this.state.seconds)===0){
this.setState(prevState => ({
pomodoro: !prevState.pomodoro,
minutes: (prevState.pomodoro ? 25 : 5),
}))
} else{
if (this.props.start){
if (this.state.seconds===0){
this.setState(prevState => ({
minutes: prevState.minutes - 1,
seconds: 59,
}))
} else{
this.setState(prevState => ({
seconds: prevState.seconds - 1
}))
}
}
}
}
render() {
return (
<View>
<Text style={styles.time}>
{("0"+this.state.minutes).slice(-2)}:
{("0"+this.state.seconds).slice(-2)}
{this.props.start}
</Text>
<View style={styles.buttonRow}>
<Button
title={this.props.buttonText}
onPress={this.props.toggleStart}>
</Button>
<Button
title="Reset"
onPress={this.reset}>
Timer.resetTime
</Button>
</View>
</View>
);
}
}
export default class App extends React.Component {
constructor (props) {
super(props)
this.state = {
start: false,
pomodoro: false,
buttonText: "Start"
}
}
toggleStart = () => this.setState(prevState => ({
start: !prevState.start,
buttonText: (prevState.start ? "Start" : "Stop")
}))
render() {
return (
<View style={styles.container}>
<Timer
start={this.state.start}
pomodoro={this.state.pomodoro}
toggleStart={this.toggleStart}
buttonText={this.state.buttonText}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
time: {
fontSize: 70,
color: 'tomato',
alignItems: 'center',
justifyContent: 'center',
},
buttonRow: {
flexDirection: 'row'
},
});