#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; ); } };