Sachin Bhusal
Sachin Bhusal

Reputation: 63

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?

Upvotes: 1

Views: 4643

Answers (2)

hong developer
hong developer

Reputation: 13906

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 };
  })

Upvotes: 2

Leo Santos
Leo Santos

Reputation: 300

To do this, you basically need:

1- To create a method that accepts a value and do something with it in the parent component.

2- Then pass that same method as props to the child component.

3- After that, inside the child component you pass in the email as an argument to the method sent from the parent.

Here's an example:

const ParentComponent = () => {
   const [email, setEmail] = useState("");

   // Step 1 create method that does something
   const emailHandler = (email) => {
      setEmail(email);
   }

   return (
      <View>
         // Step 2 pass the method as props to child
         <ChildComponent onEmail={emailHandler} />
      </View>  
   )
}

Now for the ChildComponent

const ChildComponent = (props) => {
...
...

   // Step 3 pass the email you got from the input to the parent's method
   const emailChangeHandler = () => {
      props.onEmail(email);
   }

   return (
      <View>
         <TextInput onChange={emailChangeHandler} />
      </View>  
   )
}

Upvotes: 2

Related Questions