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"
}
}
}
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
}) {