Seach Bar in react-native doesn't show any result - react-native

When I search for a name nothing appears and everything gets deleted. Also, when I delete what I typed nothing appears again.
This is the search part I hope it's understandable!
const handleSearch = text => {
const formattedQuery = text.toLowerCase();
const filteredData = filter(fullData, user => {
return contains(user, formattedQuery);
});
setData(filteredData);
setQuery(text);
};
I think the problem lays here but I don't know what to change exactly
const contains = ({ name }, query) => {
const { first, last } = name;
if (first.includes(query) || last.includes(query) ) {
return true;
}
return false;
};
return (
<View
style={{
backgroundColor: '#fff',
padding: 10,
marginVertical: 10,
borderRadius: 20
}}
>
<TextInput
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="always"
value={query}
onChangeText={queryText => handleSearch(queryText)}
placeholder="Search"
style={{ backgroundColor: '#fff', paddingHorizontal: 20 }}
/>

I think you haven't done filtering correctly.
const handleSearch = text => {
const formattedQuery = text.toLowerCase();
const filteredData = fullData.filter(user => contains(user, formattedQuery));
setData(filteredData);
setQuery(text);
};

Related

Camera does not open ReactNative with expo

I'm having a strange problem with the camera.
I'm actually trying to open the camera but I can't, could it be because of this flex?
For example, I tried to put it outside the flex component and everything worked
const Documents = () => {
const [cameraRef, setCameraRef] = React.useState(null);
const [type, setType] = React.useState(Camera.Constants.Type.back);
const [startCamera, setStartCamera] = React.useState(false)
useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
console.log(status)
setHasPermission(status === 'granted');
})();
}, []);
const takePhoto = async () => {
await setStartCamera(true);
console.log(startCamera);
}
return (
<><Header title={DOCUMENTS_TITLE}/><View>
<Flex h={150} alignItems="center">
<FormControl isRequired isInvalid>
<Center>
<Text
color="muted.500"
fontSize="md"
bold
italic
>Take photos of the documents</Text>
{
! startCamera ?
(
<Box>
<TouchableOpacity onPress={takePhoto}>
<Icon size="6xl" as={Feather} name="camera" color="muted.500"/>
</TouchableOpacity>
</Box>
)
:
(
<Camera
style={{flex: 10, width:"100%"}}
type={type}
ref={ref => {
setCameraRef(ref) ;
}}
></Camera>
)
}
</Center>
</FormControl>
</Flex>
</View></>
)
}
const styles = StyleSheet.create({
divider: {
width: 100
},
view: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
spacer: {
padding: 8
}
});
I don't really understand how to solve this error.
Can I do something specific?
For example, I just want to open the camera and be able to take a picture when I click on that icon described in the code and then be able to use the photo data

SectionList ref.scrollToLocation wrong location

while running scrollToLocation passing the correct values the scroll goes random and not in the desired position.
in the video you can see the indexes that I pass in the input.
I am hoping for an answer because it all seems correct to me.
with regard
gif:
https://i.imgur.com/EPw9AKm.gif
//#ts-ignore
const onFocus = (item, sectionIndex, itemIndex) => {
// console.log({ item, sectionIndex, itemIndex})
// setCurrentIndex(index);
onScrollToItemSelected(sectionIndex, itemIndex);
};
const onScrollToItemSelected = (sectionIndex: number, itemIndex: number) => {
console.log("onScrollToItemSelected::::", { sectionIndex, itemIndex });
// console.log("onScrollToItemSelected::refSectionList", refSectionList.scrollToLocation)
//#ts-ignore
refSectionList.scrollToLocation({
animated: true,
sectionIndex: sectionIndex,
itemIndex: itemIndex,
viewPosition: 0,
});
};
<SectionList
contentContainerStyle={{ paddingBottom: 300 }}
ref={(ref: any) => setRefSectionList(ref)}
keyExtractor={(item, index) => `sectionList-${index}`}
style={{ margin: 8, backgroundColor: "grey" }}
sections={entities}
getItemLayout={getItemLayout}
renderItem={(data) => {
const { index, item, section } = data;
const sectionIndex = section.sectionIndex;
//#ts-ignore
const { lists } = item || {};
if (!lists) return null;
return lists.map((item: any, idx: number) => {
console.log("section:::", section.sectionIndex);
return (
<ItemSection
key={`ItemSection-${sectionIndex}-${idx}`}
item={item}
index={idx}
onFocus={onFocus}
currentIndex={currentIndex}
{...section}
/>
);
});
}}
renderSectionHeader={({ section: { title, sectionIndex } }) => {
return (
<Text
style={{
color: "white",
padding: 8,
borderWidth: 1,
borderColor: "yellow",
backgroundColor: "black",
}}
>
Header {sectionIndex}
</Text>
);
}}
{...props}
/> ```

Change border color text input When its empty in react native

I want when text input is empty change border color to red with press button:
const post = () => {
let list = [];
if (homeAge === '') {
list.push('homeage')
}
}
<TextInput
style={[Styles.TextInput, { borderColor: list.includes('homeage') ? 'red' : '#006d41' }]}
onChangeText={(event) => homeAgeHandler(event)}
/>
<Button style={Styles.Button}
onPress={() => post()}>
<Text style={Styles.TextButton}>ثبت اطلاعات</Text>
</Button>
Use a useRef hook :
const ref=useRef(0);
const post = () => {
let list = [];
if (homeAge === '') {
list.push('homeage')
}
}
useEffect(()=>{
if(list.size==0&&ref.current)
{
ref.current.style.borderColor = "red";
}
},[list,ref]);
<TextInput ref={ref}
onChangeText={(event) => homeAgeHandler(event)}
/>
<Button style={Styles.Button}
onPress={() => post()}>
<Text style={Styles.TextButton}>ثبت اطلاعات</Text>
</Button>
Here is a simple example to validate text and change styling based on validation,
const App = () => {
const [text, setText] = useState("");
const [error, setError] = useState(false);
const validateText = () => {
if (text === "") {
setError(true);
} else {
setError(false);
}
};
return (
<View>
<TextInput style={[Styles.TextInput, { borderColor: error ? 'red' : '#006d41', borderWidth:'1px'}]}
onChangeText={setText}
/>
<Button style={Styles.Button}
onPress={validateText}>
<Text style={Styles.TextButton}>ثبت اطلاعات</Text>
</Button>
</View>
);
};
export default App;
TextInput empty:
TextInput not empty:
Use state instead.
Also, In the given example, you are trying to access the list which is the local variable of the post() method.
Here is the alternate solution:
export default function App() {
const [homeAge, setHomeAge] = useState('');
return (
<View style={styles.container}>
<TextInput
value={homeAge}
style={[
styles.textInput,
{ borderColor: !homeAge ? 'red' : '#006d41' },
]}
onChangeText={(text) => setHomeAge(text)}
/>
<Button title={'ثبت اطلاعات'} style={styles.button} onPress={() => {}} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
textInput: {
padding: 10,
borderWidth: 1,
},
});
Working example: Expo Snack

How to use react native TextInput selection props?

I have the following simple component:
function TestComp() {
const [selection, setselection] = React.useState({ start: 0, end: 0 });
return (
<View style={{ justifyContent: "center", flex: 1 }}>
<TextInput
selection={selection}
onSelectionChange={(event) => {
const {nativeEvent: { selection: { start, end } }} = event;
setselection({ start, end });
}}
multiline={true}
/>
</View>
);
}
My problem is that there is often a delay with the update of the value of selection through setselection, which causes the caret to jump around or trigger the error: setSpan(1 ... 1) ends beyond length 0
(Which I believe means that the selection is set to be bigger than the TextInput value)
How am I supposed to use the selection prop? My goal is to be able to move the cursor around when I need.
I am using expo, but with remote debugging off to not cause additional lag.
Jumping example:
I think this might be helpful for you.
const Test = () => {
const [style, setStyle] = useState({
TestComponent: {
backgroundColor: "white",
height: 40,
borderWidth: 1,
},
});
const [selection, setSelection] = useState({
start: 0,
end: 0,
});
const [txt, setTxt] = useState("");
return (
<TextInput
style={style.TestComponent}
selection={selection}
value={txt}
multiline={true}
onChangeText={(changedTxt) => {
setTxt(changedTxt);
console.log("onChangeText", selection);
}}
onSelectionChange={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent;
const { selection } = nativeEvent;
console.log("onSelectionChange", selection);
setSelection(selection);
}}
/>
);
};

Is there anyway to check if a functional component is doing unnecessary re-rendered?

here is what i'm doing
here are those circle component
const Item = (props) => {
// console.log(props)
const [count, setCount] = useState(0);
console.log('aaa')
return (
<TouchableOpacity style={{ width: containerSize, height: containerSize, padding: PADDING, justifyContent: "center", alignItems: "center" }}
onPress={() => {
count == 0 ? setCount(1) : setCount(0)
}}
>
<View style={[count == 0 ? { backgroundColor: '#fff' } : { backgroundColor: '#3ba39a' },
{
width: itemSize, height: itemSize, borderRadius: containerSize / 2,
justifyContent: "center", alignItems: "center",
transform: [{ rotate: '-90deg' }]
}]} >
<Text>{props.x}</Text>
</View>
</TouchableOpacity>
)
}
const MemoizedItem = memo(Item);
and the render method
addItem(){
this.map = [];
for (let col1 = 0; col1 < itemPerCol; col1++) {
this.map[col1] = [];
for (let row1 = 0; row1 < itemPerRow; row1++) {
this.map[col1][row1] = <MemoizedItem x={row1} y={col1} />
}
}
this.setState({ map: this.map })
}
renderItem() {
return this.state.map.map((row) => {
return row.map((item) => {
return item;
})
})
}
The ideal is when you click on a circle, the color change and the other circle not render again.
I'm trying using memo like above but it still so laggy.
Is there any way to make a better performance and is there any way to check if not clicked circle is re-rendered?
Use useMemo to memo component's props and state.
Pass [ props.x, props.y, count ] to make component re-render only when some of that values change.
import { useMemo } from 'react';
const Item = (props) => {
const [count, setCount] = useState(0);
return useMemo(() => (
<TouchableOpacity>
{ console.log(`Item x${props.x}-y${props.y} render`) }
...
</TouchableOpacity>
), [ props.x, props.y, count ]);
};
Add key props to make sure that Item component will not re-mount.
<Item key={`x${row1}-y${col1}`} x={row1} y={col1} />