0

I have weird issue with TextInput places as headerTitle in React Navigation. I made a compontent containing TextInput and Button:

const SearchBox = ({handleSearch, setSearchTerm, iconSize, cleanSearch, searchTerm}) => {
    const animation = useSharedValue(0);
    const animatedStyle = useAnimatedStyle(() => {
        return {
            width: withTiming(`${animation.value * 100}%`, {duration: 500}),
            borderWidth: withTiming(animation.value, {duration: 500}),
            paddingLeft: withTiming(animation.value * 10, {duration: 500})
        }
    })
    
    useEffect(() => {
        animation.value = 1;
    }, [])

    return (
        <Animated.View style={[styles.inputContainer, animatedStyle]}>

            <TextInput style={styles.textInput}
                       placeholder='Wpisz szukaną frazę'
                       value={searchTerm}
                       onChangeText={text => setSearchTerm(text)}
                       onSubmitEditing={handleSearch} />

            <View style={styles.collapseButtonContainer}>
                <TouchableOpacity onPress={cleanSearch}>
                    <Ionicons name={'close-outline'} size={iconSize ? iconSize : 24} color={COLORS.gray}/>
                </TouchableOpacity>
            </View>

        </Animated.View>
    )
}

I am trying to use it as headerTitle in React Navigation Header like this:

    const [searchTerm, setSearchTerm] = useState("");
    const [toggleSearch, setToggleSearch] = useState(true)
    
    const handleSearch = () => {
        setToggleSearch(prev => !prev);
    }
    const cleanSearch = () => {
        setSearchTerm("");
        setToggleSearch(prev => !prev);
    }


    useEffect(() => {
        navigation.setOptions({
            headerShown: true,
            headerStyle: { backgroundColor: COLORS.lightWhite, height: 120 },
            headerLeft: () =>  <BackArrowWithText navigation={navigation} />,
            headerTitle: () => <View style={{overflow: 'hidden', alignItems: 'flex-end'}}>
                <SearchBox handleSearch={() => handleSearch()} searchTerm={searchTerm} setSearchTerm={setSearchTerm} cleanSearch={() => cleanSearch()} />
            </View>,
            headerTitleAlign: 'left',
        })
    }, [navigation])

The problem is: Whenever I am trying to type something in this input my character is instatly removed from it. If I set initialValue of "searchTerm" hook problem appears, but if not it doesn't, instead can't use "cleanSearch" method to set value to empty string (This is crucial, because I passing empty string to an API call).

The problem is only when I use this component inside header (does not matter if as headerTitle, headerLeft or right). If I use it inside other components it works perfectly.

I am pretty sure I am doing something wrong using hooks within header, but really I do not know. I already tried:

  • using "onChange" instead of "onChangeText" - same effect.
  • creating component as useCallback inside main component - same effect.
  • trying to useRef instead of useState - same effect.

Every time it is going back to its initial value. Please help.

  • 1
    One thing that catches my eye: `navigation` as `useEffect` dependency is probably invalid (can't tell for sure b/c I don't know how it's created) and might cause to many invokations of this callback. (And also, `searchTerm` is probably a dependeny you need there`). – NotX Jul 13 '23 at 18:11
  • Like 5 minutes before your answer I figured it out, that I was missing searchTerm in useEffect dependency, that's why it was going back to its previous state (technically not re-rendering header with new value). Thank you for your time! :) – Świętopeł Ziemowit Jul 13 '23 at 18:32

0 Answers0