Reputation: 63
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
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
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