Как исправить ошибку дочернего компонента, не передающего данные обратно своему родителю? Сообщение об ошибке: Ошибка типа: this.props… не является функцией. Реагируйте на Родной язык

#javascript #react-native

Вопрос:

Я успешно визуализирую дочерний компонент (lt; SavingRecipeAnimationAlmost /gt;) внутри его родительского компонента (lt; SavingRecipeAnimationAlmost /gt;lt; Почти список /gt;).

Все работает так, как должно, пока не дойдет до дочернего компонента, возвращающего состояние var в своей функции finish() через свойство animationOver.

Я получаю это сообщение об ошибке: «ошибка: this.props.animationOver не является функцией. (В «this.props.animationOver(состояние)», «this.props.animationOver» не определено)», и он не будет передавать данные и запускать функцию animationOver() в родительском компоненте, как это должно быть.

Вот мои компоненты, заранее спасибо, если вы вообще можете помочь:

Дочерний компонент:

 class SavingRecipeAnimationAlmost extends React.Component{  constructor(props){  super(props);  this.state = {  fiveSecondsOver: false,  }  this.componentDidMount = this.componentDidMount.bind(this)  this.componentDidUpdate = this.componentDidUpdate.bind(this)  this.componentWillUnmount = this.componentWillUnmount.bind(this)  this.fiveSecondStopwatch = this.fiveSecondStopwatch.bind(this)  this.finish = this.finish.bind(this)   this.opacity = new Animated.Value(0.01);  this.abortController = new AbortController()   Animated.loop(  Animated.sequence([  Animated.timing(this.opacity, {  duration: 1000,  toValue: 1,  easing: Easing.linear,  useNativeDriver: false,  signal: this.abortController.signal,  }),  Animated.delay(1000),  Animated.timing(this.opacity, {  duration: 1000,  toValue: 0,  easing: Easing.linear,  useNativeDriver: false,  signal: this.abortController.signal,  }),  ]),  ).start()   };   componentDidMount(){  console.log("SavingRecipeAnimationAlmost mounted")  this.fiveSecondStopwatch()  }   componentDidUpdate(){  console.log("SavingRecipeAnimationAlmost updated")  console.log("Five seconds over?: "   this.state.fiveSeAlmostcondsOver)  }   componentWillUnmount(){  console.log("SavingRecipeAnimationAlmost unmounted")  this.abortController.abort()  }   fiveSecondStopwatch(){  console.log("FIVE SECONDS started")  var cmponent = this  setTimeout(function(){  console.log("FIVE SECONDS finished")  cmponent.setState({  fiveSecondsOver: true,  }),  cmponent.finish()  }, 5000);  }   finish(){  var state = false  try{  this.props.animationOver(state)  }catch(error){  console.log("error: "   error.message)  }  }   render(){  console.log("SavingRecipeAnimationAlmost rendered")  var five_seconds_over = this.state.fiveSecondsOver   return(  lt;Viewgt;   {five_seconds_over === false amp;amp;  lt;Animated.Text style={{  opacity: this.opacity.interpolate({  inputRange: [0,1],  outputRange: [0,1],  }),  fontSize: 18,  marginTop: 10,  fontWeight:'bold',  textAlign: 'center',  color: 'lightseagreen'  }} gt; Saving recipe... lt;/Animated.Textgt;  }   {five_seconds_over amp;amp;  lt;Text style={styles.greenTitle}gt; Saved! lt;/Textgt;  }   lt;/Viewgt;  );   }  };  

Родительский компонент:

 class AlmostList extends React.Component{ constructor(props){  super(props);  this.state = {  almostList: this.props.almosts,  savedRecipeIndexes: [],  urlsSavedInThisSearch: this.props.url_list,  prevUrlLength: '',  savedRecipeInfo: this.props.saved_recipes_info,  showAnimation: false,  recipeClicked: ''  }  this.componentDidMount = this.componentDidMount.bind(this)  this.componentDidUpdate = this.componentDidUpdate.bind(this)  this.componentWillUnmount = this.componentWillUnmount.bind(this)   this.sendBackRecipeToSave = this.sendBackRecipeToSave.bind(this)  this.animationOver = this.animationOver.bind(this) };  componentDidMount(){  console.log("Almost list mounted")  if(this.state.savedRecipeInfo !== undefined){  for([key,value] of Object.entries(this.state.savedRecipeInfo)){  console.log("**didMount** key: "   key   " value: "   value)  }  } }  componentDidUpdate(){  console.log("Almost list updated")  console.log("UPDATE showAnimation?: "   this.state.showAnimation) }  componentWillUnmount(){  console.log("Almost list dismounting") }  animationOver(state){  console.log("animationOver function")  this.setState({  showAnimation: state  }) }  sendBackRecipeToSave(recipe,index){  console.log("ALMOST SAVE CLICKED")  var recipes_saved = this.state.savedRecipeIndexes  recipes_saved.push(index)  var saved_recipe_info = this.state.savedRecipeInfo  var url_list = this.state.urlsSavedInThisSearch   if(recipe.length === 3){  var url = recipe[1]  var missing = recipe.pop()  saved_recipe_info[url] = missing  url_list.push(url)  }   var ind = ''  this.props.newRecipeToSave(recipe,ind,url_list,saved_recipe_info)  this.setState({  savedRecipeIndexes: recipes_saved,  urlsSavedInThisSearch: url_list,  savedRecipeInfo: saved_recipe_info,  recipeClicked: index,  showAnimation: true  }) }  render(){  var recipe_list = this.state.almostList  var saved_urls = this.state.urlsSavedInThisSearch  var urls_are_saved = false  if(saved_urls !== undefined){  urls_are_saved = true  }  var saved_recipe_info = this.state.savedRecipeInfo  var self = this  var show_animation = this.state.showAnimation  var recipe_clicked = this.state.recipeClicked   return(   lt;Viewgt;   {recipe_list.map(function(item,index) {   return(  lt;View key={index}gt;  lt;View style={{justifyContent:"center",alignItems:"center"}}gt;  lt;Text style={{justifyContent:"center",fontSize:18,fontWeight:'bold',  textAlign:"center",marginBottom:10,marginTop:30}}gt;{item[0]}lt;/Textgt;   {item.length === 3 amp;amp;  lt;Text style={{fontWeight:"bold",marginBottom:5,textAlign:"center"}}gt;Missing ingredient: {item[2]}lt;/Textgt;  }  {item.length === 2 amp;amp; urls_are_saved amp;amp; saved_recipe_info !== undefined amp;amp;  lt;Viewgt;  {Object.entries(saved_recipe_info).map(function(info,ind) {  return(  lt;View key={ind}gt;  {saved_urls.includes(info[0]) amp;amp; item[1] === info[0] amp;amp;  lt;Text style={{fontWeight:"bold",marginBottom:5,textAlign:"center"}}gt;Missing ingredient: {info[1]}lt;/Textgt;  }  lt;/Viewgt;  )  })  }  lt;/Viewgt;  }  { show_animation === false amp;amp;  lt;View style={{justifyContent:"center",alignItems:"center"}}gt;  lt;Pressable style={{justifyContent:"center"}} onPress={() =gt; Linking.openURL(`${item[1]}`)}gt;  lt;Text accessible={true} accessibilityLabel="Go to recipe website" accessibilityRole="link"  style={styles.greenButton}gt;Go to recipe websitelt;/Textgt;  lt;/Pressablegt;  { saved_urls.includes(item[1]) amp;amp;  lt;Pressable style={{justifyContent:"center"}}gt;  lt;Text accessible={true} accessibilityLabel="Recipe has been saved"  accessibilityRole="button" style={styles.redButton}gt;Recipe savedlt;/Textgt;  lt;/Pressablegt;  }  { !(saved_urls.includes(item[1])) amp;amp;  lt;Pressable style={{justifyContent:"center"}} onPress={() =gt; self.sendBackRecipeToSave(item,index)}gt;  lt;Text accessible={true} accessibilityLabel="Save this recipe to your device"  accessibilityRole="button" style={styles.greenButton}gt;Save recipelt;/Textgt;  lt;/Pressablegt;  }  lt;/Viewgt;  }  { show_animation amp;amp;  lt;View style={{justifyContent:"center",alignItems:"center"}}gt;  lt;Pressable style={{justifyContent:"center"}}gt;  lt;Text accessible={true} accessibilityLabel="Go to recipe website" accessibilityRole="link"  style={styles.greenButton}gt;Go to recipe websitelt;/Textgt;  lt;/Pressablegt;  { saved_urls.includes(item[1]) amp;amp;  lt;Pressable style={{justifyContent:"center"}}gt;  lt;Text accessible={true} accessibilityLabel="Recipe has been saved"  accessibilityRole="button" style={styles.redButton}gt;Recipe savedlt;/Textgt;  lt;/Pressablegt;  }  { !(saved_urls.includes(item[1])) amp;amp;  lt;Pressable style={{justifyContent:"center"}}gt;  lt;Text accessible={true} accessibilityLabel="Save this recipe to your device"  accessibilityRole="button" style={styles.greenButton}gt;Save recipelt;/Textgt;  lt;/Pressablegt;  }  { recipe_clicked === index amp;amp;  lt; SavingRecipeAnimationAlmost  animationOver={this.animationOver}  /gt;  }  lt;/Viewgt;  }   lt;/Viewgt;  lt;/Viewgt;  )  })   }   lt;/Viewgt;   );   }   };