How to pass entered input value from child to parent component in react native

I have a InputField component which I have to use many times in other parent components. Now what I want is to pass the user's entered email and password to Login(parent) component. This is what I did,

Inputfield.js

const InputField = ({
  isIcon = false,
  secureTextEntry = false,
  placeholder,
  onFieldChange
  }) => {
  const [isActive, setIsActive] = useState(false);
  const [fieldText, setFieldText] = useState("");

  return (
    <View
      style={{
        ...styles.container,
        borderColor: isActive ? "blue" : "#efefef",
      }}>
      {isIcon ? (
        <Feather
          name="search"
          size={24}
          color={isActive ? "blue" : "black"}
          style={styles.searchIcon}
        />
      ) : null}
      <TextInput
        style={styles.input}
        value={fieldText}
        onChangeText={(text) => {
          setFieldText(text);
          onFieldChange(!secureTextEntry, text);
        }}
        onFocus={() => {
          setIsActive(true);
        }}
        placeholder={placeholder}
        autoCorrect={false}
        selectionColor={"blue"}
        secureTextEntry={secureTextEntry}
      />
    </View>
  );
};

Login.js

const Login = () => {
  const [user, setUser] = useState({ email: null, password: null });

  const onUserChange = (email, text) => {
    setUser(email ? { email: text, ...user } : { ...user, password: text };
  });

  const handleLogin = async () => {
    try {
      const res = await axios.post("http://192.168.1.40:8000/login", user);
      console.log("got login response", res.data);
    } catch (error) {
      console.log("Post failed", error.message);
    }
  };

  const [isFontLoaded] = useFonts({ Arapey_400Regular_Italic });

  if (!isFontLoaded) return <AppLoading />;

  return (
    <View style={styles.login}>
      <BackgroundImageEffect />
      <View
        style={{
          alignSelf: "flex-start",
          position: "absolute",
          top: variables.DIMENSIONS.height / 4,
          left: 15,
        }}>
        <Text
          style={{
            fontSize: 50,
            fontFamily: "Arapey_400Regular_Italic",
            color: "blue",
          }}>
          Login
        </Text>
        <View style={{ borderWidth: 1, borderColor: "blue" }}></View>
      </View>
      <View style={styles.form}>
        <View style={{ marginVertical: 10 }}>
          <InputField
            placeholder="Email or Phone"
            onFieldChange={onUserChange}
          />
        </View>
        <View style={{ marginVertical: 10 }}>
          <InputField
            placeholder="Password"
            onFieldChange={onUserChange}
            secureTextEntry={true}
          />
        </View>
        <View
          style={{ width: "50%", alignSelf: "flex-end", marginVertical: 10 }}>
          <TouchableHighlight
            style={{
              width: "100%",
              backgroundColor: "blue",
              borderRadius: 20,
              height: 40,
              justifyContent: "center",
            }}
            activeOpacity={0.3}
            underlayColor="efefef"
            onPress={() => handleLogin()}>
            <Text
              style={{
                color: "white",
                fontFamily: "Arapey_400Regular_Italic",
                fontSize: 24,
                textAlign: "center",
              }}>
              Login
            </Text>
          </TouchableHighlight>
        </View>
      </View>
    </View>
  );
};

When I send the request using Postman, server responds correctly. But after pressing login button with the same request body login fails. That means there is something wrong while setting the user. So, What is the best way to pass that entered details to parent component?


Solution 1:

This is a very simple matter. It is an error in the Spread syntax.

about Spread syntax of MDN document

you can change this

 const onUserChange = (email, text) => {
    setUser(email ? { ...user, email: text } : { ...user, password: text };
  })