Search code examples
react-nativestatereact-props

React child prop doesn't change when parent state updates


I have a react native app and I want to update some states and pass a prop to other components. I am passing the focus state and setFocus to the "Search" component. The focus state on the "Vault" component updates properly but it doesn't affect the "Search" component. The code is like below. What am I doing wrong?

const Vault = ({ navigation }: VaultStackNavigationProps<"Vault">) => {
  const [focus, setFocus] = useState(false);

  React.useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: () => (
        <Right isFocus={focus}>
          <Search handleFocus={setFocus} focus={focus} />
        </Right>
      ),
    });
  }, [navigation]);
  return (
    <Box style={{ flex: 1, backgroundColor: "#1A1A1A" }}>
      <Text color="white">hello</Text>
    </Box>
  );
};

export const Search = ({ handleFocus, focus }) => {
  const [value, setValue] = useState("");
  const inputRef = useRef<TextInput>();
  const { width } = useWindowDimensions();

  const onHandleFocus = (value) => {
    handleFocus(value);
  };

  useEffect(() => {
    if (focus) {
      inputRef.current.focus();
    } else {
      Keyboard.dismiss();

      clearTextState();
    }
  }, [focus]);

  const clearTextState = () => {
    setValue("");
  };
  const onClear = () => {
    clearTextState();
    inputRef.current.clear();
  };

  const onClose = () => {
    onHandleFocus(false);
  };
  return (
    <>
      {focus && (
        <TouchableOpacity onPress={onClose}>
          <MaterialIcons name="arrow-back" size={24} color="white" />
        </TouchableOpacity>
      )}
      {focus && (
        <TextInput
          ref={inputRef}
          style={{
            flex: 1,
            color: "white",
            paddingLeft: 15,
            fontFamily: "CrimsonRegular",
          }}
          onChangeText={(text) => setValue(text)}
          placeholder="Type here"
        />
      )}
      {focus && value.length > 0 && (
        <SearchIconButton
          onPress={onClear}
          style={{ width: width / 9 }}
          icon="close"
        />
      )}
    </>
  );
};

Solution

  • Your layoutEffect is listening changes only from navigation

    Try adding focus to useLayoutEffect array like

    React.useLayoutEffect(() => {
        navigation.setOptions({
          headerRight: () => (
            <Right isFocus={focus}>
              <Search handleFocus={setFocus} focus={focus} />
            </Right>
          ),
        });
      }, [navigation, focus]);