作为 prop 传递的函数在 React Native 中不起作用

问题描述 投票:0回答:1
我的代码遇到问题,所以基本上我有一个名为

StoreScreen 的函数

我将我创建的搜索栏称为

SearchBar,并且从StoreScreen我需要访问searchBar的onFocus,问题给我如下,首先让我向您展示代码:

Pd。如果你想知道我的环境和版本,我就直接留到下面吧

import { View, Text, TextInput, ScrollView, Button, Image } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import SliderComponent from "../Components/SliderComponents"; import ProductComponent from "../Components/ProductHorizontalComp"; import Stores from "../Data/Stores"; import { useState } from "react"; import FruitsAndVeggies from "../Data/FruitsAndVeggies"; import Akcijos from "../Data/Akcijos"; import useMiniSearch from "../Search/MiniSearchEngine"; import SearchBar from "../Components/Generic/SearchBar"; import genericStyles from "../Styles/genericStyles"; /** * * @returns Component with the main page where all the stores and the basic prodcuts are shown */ export default function StoreScreen({ navigation }) { //variables to controll const [isSearchFocused, setIsSearchFocused] = useState(false); const [searchResults, setSearchResults] = useState([]); const { results, search, autosuggest, autosuggestResults, searchIndex } = useMiniSearch(FruitsAndVeggies, { fields: ["name"] }, { fuzzy: 0.2 }); //function to handle when the text is changed in the search bar const handleChangeText = (text) => { autosuggest(text); setSearchResults(results); }; /** * Header that shows the title on the left and a Button on the right * @param {string} titleText What will be shown on the title * @param {Function} handleOnPress Function that will be called when pressed on the Button * @param {string} buttonTitle Title of the button * @returns */ const viewAllHeader = (titleText, handleOnPress, buttonTitle = "ViewAll") => { return ( <View style={{ flex: 1, paddingTop: 20, flexDirection: "row", justifyContent: "space-between", alignItems: "center", }} > <Text style={{ paddingHorizontal: 20, fontSize: 24, fontWeight: "700", }} > {titleText} </Text> <Text style={{ paddingHorizontal: 20, color: "#00da34" }} onPress={handleOnPress} > View All {">"} </Text> </View> ); }; const consl = () => console.log("Focused"); return ( <SafeAreaView style={{ flex: 1 }}> <SearchBar border={true} handleOnFocus={consl} /> {/* Horizontal SrollView */} <ScrollView> {/* Horizontal scrollView of all the stores */} {viewAllHeader("Stores", () => navigation.navigate("ViewAll", { array: Stores, title: "Stores", type: 0, }) )} <ScrollView style={{ marginTop: 10 }} horizontal={true} showsHorizontalScrollIndicator={false} > {Stores.map((store) => ( <SliderComponent key={store.Id} // Make sure to provide a unique key for each SliderComponent name={store.name} image={store.Logo} /> ))} </ScrollView> {/* Fruits and veggies */} {viewAllHeader("Fruits and Veggies", () => navigation.navigate("ViewAll", { array: FruitsAndVeggies, title: "Fruits and vegetables", type: 1, }) )} <ScrollView style={{ marginTop: 10 }} horizontal={true} showsHorizontalScrollIndicator={false} > {FruitsAndVeggies.map((item) => ( <ProductComponent image={item.image} store={item.store} name={item.name} quantity={item.quantity} quantityType={item.quantityType} price={item.price} isCardDiscounted={item.isCardDiscounted} discountPrice={item.discountPrice} navigation={navigation} soldBy={item.soldBy} key={item.id} /> ))} </ScrollView> {/* Actual discounts */} {viewAllHeader("Other discounts", () => navigation.navigate("ViewAll", { array: FruitsAndVeggies, title: "Fruits and vegetables", type: 1, }) )} {/* Discount Posts */} <ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={{ marginTop: 10, paddingRight: 20 }} > {Akcijos.map((item) => ( <ProductComponent key={item.id} navigation={navigation} image={item.image} store={item.store} name={item.name} quantity={item.quantity} price={item.price} discountPrice={item.discountPrice} isCardDiscounted={item.isCardDiscounted} soldBy={item.soldBy} /> ))} </ScrollView> </ScrollView> </SafeAreaView> ); }

StoreScreen 中,我调用组件 SearchBar,它是我创建的可重用搜索栏。

这是

SearchBar 组件:

import { View, TextInput, StyleSheet } from "react-native"; import { Ionicons } from "@expo/vector-icons"; /** * Generic bar Component * @param {boolean} border shows border if true * @param {number} iconSize size of the icon of the search bar * @param {StyleSheet.NamedStyles} addStyles add styles to the search bar * @param {string} placeholder string that is shown in the search bar * @param {Function} onFocus function for onFocus() * @param {Function} onChangeText function for onChangeText() * @param {Function} onBlur function for onBlur() * @returns Generic SearchBar component */ export default function SearchBar( border = false /** Variant option **/, iconSize, addStyles /** Variant option **/, placeholder = "search" /** Variant option */, handleOnFocus /** Default prop **/, onChangeText, onBlur ) { return ( <View style={[Styles.searchbarView, addStyles]}> <Ionicons name="search" size={20} /> <TextInput style={{ flex: 1, marginLeft: 5, justifyContent: "center", fontSize: 16, }} placeholder={placeholder} onChangeText={onChangeText} onFocus={() => { console.log(handleOnFocus); handleOnFocus(); }} onBlur={onBlur} /> </View> ); } const Styles = StyleSheet.create({ searchbarView: { height: 35, justifyContent: "flex-start", alignItems: "center", flexDirection: "row", marginTop: 30, borderColor: "#1ACE2B", borderWidth: 1, borderRadius: 7, paddingHorizontal: 10, marginHorizontal: 20, }, });
我遇到的问题是,当我调用 

SearchBar 组件并尝试调用其函数之一时,它给我错误“* ERROR TypeError:handleOnFocus 不是函数”。 (在'handleOnFocus()'中,'handleOnFocus'未定义)' *。看来handleOnFocus prop始终为空并且不会被传递。

我尝试将函数直接放在

SearchBar 调用中 <SearchBar border={true} handleOnFocus={() => console.log("focused")} />

我尝试过这样做
<SearchBar border={true} handleOnFocus={console.log("focused")} />
我尝试像这样初始化handleOnFocus的道具:

... export default function SearchBar( border = false /** Variant option **/, iconSize, addStyles /** Variant option **/, placeholder = "search" /** Variant option */, {handleOnFocus} /** Default prop **/, onChangeText, onBlur ) { ...
他们都告诉我“handleOnFocus”未定义或者它不是一个函数。
通过一些 ifs 和 console.log 我发现 

handleOnClose 始终是未定义的。

我正在使用的版本:

{ "expo": { "name": "Program", "slug": "Program", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", "userInterfaceStyle": "light", "splash": { "image": "./assets/splash.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, "updates": { "fallbackToCacheTimeout": 0 }, "assetBundlePatterns": [ "**/*" ], "ios": { "supportsTablet": true }, "android": { "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#FFFFFF" } }, "web": { "favicon": "./assets/favicon.png" } } }
    
javascript react-native function onfocus
1个回答
0
投票
这是对 React 中 props 传递方式的误解。组件将所有 props 传递给单个对象。举个例子:

const MyComponent = (props) => { return ( <Text>{JSON.stringify(props)}</Text> ); }; const ParentComponent = () => { return ( <MyComponent prop1='hello' prop2={42} /> ); };
在屏幕上您应该看到:

{"prop1":"hello","prop2":42}

,显示所有道具都组合成该单个对象。

在问题的示例中,您尝试接收道具,就好像它们都作为不同的参数单独传递给您的组件一样。

export default function SearchBar( border = false /** Variant option **/, iconSize, // ...
按照它的写法,你所有的 props 都会被传递到你的 

border

 props 中。其他道具都将是未定义的。

在导入行中解构 props 对象是很常见的。这样,您就可以访问您的道具,而无需指定

props.prop1

 等。在我上面放置的示例组件中,它看起来像

const MyComponent = ({ prop1, prop2 }) => { return ( <Text>{prop1}, {prop2}</Text> ); };
对组件最简单的编辑就是做同样的事情,并解构组件参数中的 props。

export default function SearchBar({ border = false /** Variant option **/, iconSize, addStyles /** Variant option **/, placeholder = "search" /** Variant option */, {handleOnFocus} /** Default prop **/, onChangeText, onBlur }) {
    
© www.soinside.com 2019 - 2024. All rights reserved.