On first render, getting "Error: Rendered more hooks than during the previous render" -- fixed on reset and next load #2441
-
/* eslint-disable react-native/no-inline-styles */
import { observer } from "mobx-react-lite"
import React, { FC, useRef, useState, useEffect } from "react"
import { Animated, TextInput, TextStyle, View, ViewStyle } from "react-native"
import { Button, Header, Screen, SelectField, Text, TextField } from "../../../components"
import { useStores } from "../../../models"
import { AppStackScreenProps } from "../../../navigators"
import { colors, spacing, typography } from "../../../theme"
import { AntDesign } from "@expo/vector-icons"
import { doRequest } from "../../../requests/request.js"
import { baseApiUrl } from "../../../constants/constant.js"
import useSwr from "swr"
import Error from "../../../components/Error"
import Spinner from "../../../components/Spinner"
interface ComplainScreenProps extends AppStackScreenProps<"CreateComplain"> {}
export const ComplainScreen: FC<ComplainScreenProps> = observer(function ComplainScreen(_props) {
const {
navigation,
route: {
params: { isEdit, editData },
},
} = _props
const {
authUser: { authToken },
} = useStores()
const options = {
method: "GET",
headers: {
Authorization: `Bearer ${authToken}`,
},
}
// Use the useSwr hook to get the home screen data
const [selectedTeam, setSelectedTeam] = useState<string[]>([""]);
const [isSubmitting, setIsSubmitting] = useState(false);
const [successMessage, setSuccessMessage] =useState("");
const [formData, setFormData] = useState({
subject: "",
message: "",
})
const complainTitleRef = useRef<TextInput>()
const complainDescriptionRef = useRef<TextInput>()
const { data, error, isLoading } = useSwr("product", (url) => doRequest(url, options),{keepPreviousData:true});
if (isLoading) {
return <Spinner />
}
if (error) {
return <Error message={error?.message} />
}
useEffect(() => {
console.log("isEdit: ",isEdit);
if (isEdit) {
setFormData({
subject: editData?.subject,
message: editData?.message,
})
}
}, [isEdit])
const selectOptions = data
? data?.product.map((item) => {
console.log(item?.type?.name);
return ({
label: `${item?.type?.name} No: ${item?.product_unique_id}` || "-",
value: item?.id || 0,
})
}
)
: []
const handleFormChange = (key, value) => {
setFormData({
...formData,
[key]: value,
})
}
async function submitComplain() {
setIsSubmitting(true);
const data = {
...formData,
product_id:selectedTeam[0],
}
const errors: string[] = []
if (!isEdit && !data.product_id) {
errors.push("Please select a product")
}
if (!data.subject) {
errors.push("Please enter a subject")
}
if (!data.message) {
errors.push("Please enter a message")
}
if (errors.length > 0) {
alert(errors.join("\n"))
setIsSubmitting(false);
return
}
try {
const optionPost = {
method: "POST",
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(data),
}
const response = await fetch(
isEdit
? `${baseApiUrl}/complain/update/${editData.complainId}`
: `${baseApiUrl}/complain/create`,
optionPost,
)
if (response.status === 200) {
setFormData({
message: "",
subject: "",
})
complainTitleRef.current?.clear()
complainDescriptionRef.current?.clear()
setSelectedTeam([])
setSuccessMessage(isEdit ? `Your complain successfully updated!` : `Your complain successfully added!`);
navigation.navigate("Demo",{screen:'ComplainList'})
setIsSubmitting(false);
}
} catch (error) {
alert(`submitting form data: ${error?.message}`)
console.log("submitting form data", error)
setIsSubmitting(false)
}
setIsSubmitting(false)
}
let selectFieldComponent = null;
if (!isEdit) {
selectFieldComponent = (
<SelectField
label="Select Unit"
placeholder={isEdit ? editData?.productLabel : "Select Bill Type"}
value={selectedTeam}
placeholderTextColor="#00000"
onSelect={setSelectedTeam}
options={selectOptions}
LabelTextProps={{ style: $numberLabelStyle }}
multiple={false}
containerStyle={{ marginBottom: spacing.large, marginTop: spacing.large }}
inputWrapperStyle={$selectFieldWrapper}
onSubmitEditing={() => complainTitleRef.current?.focus()}
/>
);
}
useEffect(() => {
const unsubscribe = navigation.addListener("beforeRemove", (e) => {
// Prevent default behavior of leaving the screen
e.preventDefault();
// Reset the form data and navigate away from the screen
setFormData({
subject: "",
message: "",
});
complainTitleRef.current?.clear();
complainDescriptionRef.current?.clear();
setSelectedTeam([]);
navigation.dispatch(e.data.action);
});
console.log("Close");
// Cleanup the event listener when the component unmounts
return unsubscribe;
}, [navigation]);
return (
<Screen
preset="auto"
contentContainerStyle={$screenContentContainer}
safeAreaEdges={["top", "bottom"]}
>
<Header
titleMode="flex"
LeftActionComponent={
<View style={$customLeftAction}>
<AntDesign
name="arrowleft"
size={24}
color="black"
onPress={() => navigation.navigate("Demo",{screen:'ComplainList'})}
/>
</View>
}
safeAreaEdges={[]}
title="Complaints"
titleStyle={$titleStyles}
style={$headerStyle}
/>
<Text
testID="login-heading"
tx={isEdit ? `complainScreen.update` : `complainScreen.title`}
preset="heading"
style={$signIn}
/>
{
successMessage ?(
<Animated.View style={$animationContainer}>
<Text style={$animationText}>{successMessage}</Text>
</Animated.View>
):null
}
{selectFieldComponent}
<TextField
ref={complainTitleRef}
value={formData.subject}
onChangeText={(value) => handleFormChange("subject", value)}
inputWrapperStyle={[$numberField, { minHeight: 60 }]}
style={$inputFieldStyle}
autoCapitalize="none"
autoCorrect={true}
LabelTextProps={{ style: $numberLabelStyle }}
keyboardType="default"
multiline
labelTx="complainScreen.titleFieldLabel"
onSubmitEditing={() => complainDescriptionRef.current?.focus()}
placeholderTx="complainScreen.complainTitlePlaceholderTxt"
placeholderTextColor="gba(51, 65, 85, 0.12)"
/>
<TextField
ref={complainDescriptionRef}
value={formData.message}
onChangeText={(value) => handleFormChange("message", value)}
inputWrapperStyle={[$numberField, { minHeight: 110 }]}
containerStyle={$inputFieldStyle}
autoCapitalize="none"
autoCorrect={true}
multiline
LabelTextProps={{ style: $numberLabelStyle }}
keyboardType="default"
labelTx="complainScreen.descriptionLabel"
placeholderTx="complainScreen.complainDescPlaceholderTxt"
placeholderTextColor="gba(51, 65, 85, 0.12)"
/>
<Button
testID="login-button"
text={`${isSubmitting ? "Submitting..." : "Submit"}`}
disabled={isSubmitting}
style={$tapButton}
textStyle={$tabButtonTextStyle}
onPress={submitComplain}
/>
</Screen>
)
})
const $animationContainer:ViewStyle= {
backgroundColor: '#4CAF50',
padding: 10,
borderRadius: 5,
marginBottom: 20,
}
const $animationText:TextStyle= {
color: '#FFFFFF',
fontSize: 18,
}
const $screenContentContainer: ViewStyle = {
paddingHorizontal: spacing.facilityApp.horizontalPadding,
backgroundColor: colors.palette.facilityApp.screenBackground,
}
const $customLeftAction: ViewStyle = {}
const $selectFieldWrapper: ViewStyle = {
backgroundColor: colors.palette.neutral100,
}
const $headerStyle: ViewStyle = {
backgroundColor: colors.palette.facilityApp.screenBackground,
}
const $titleStyles: TextStyle = {
fontSize: spacing.medium,
fontFamily: typography.fonts.sansSerif.medium,
}
const $signIn: TextStyle = {
fontWeight: "700",
fontSize: 24,
letterSpacing: 0.3,
color: "#334155",
marginBottom:15
}
const $numberLabelStyle: TextStyle = {
color: colors.palette.facilityApp.labelColor,
fontFamily: typography.fonts.sansSerif.normal,
fontWeight: "400",
fontSize: 14,
lineHeight: 16,
fontStyle: "normal",
}
const $inputFieldStyle: ViewStyle = {
marginTop: 19,
}
const $numberField: ViewStyle = {
marginTop: 10,
height: spacing.facilityApp.inputFieldHeight,
borderColor: colors.palette.facilityApp.borderColor,
borderRadius: spacing.facilityApp.inputBorderRadius,
backgroundColor: colors.palette.neutral100,
}
const $tapButton: ViewStyle = {
backgroundColor: colors.palette.facilityApp.bigButton,
marginTop: 100,
shadowColor: colors.palette.neutral900,
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.2,
shadowRadius: 5,
elevation: 12,
height: 49,
marginBottom: "21%",
}
const $tabButtonTextStyle: TextStyle = {
fontWeight: "700",
fontStyle: "normal",
fontSize: 18,
lineHeight: 22,
color: "#FFFF",
}
// @demo remove-file |
Beta Was this translation helpful? Give feedback.
Answered by
abdulmateentechbits
May 23, 2023
Replies: 1 comment 1 reply
-
The problem likely exists elsewhere in your code. Unfortunately, I can't see anything obviously wrong here. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for your response i have solved it actually i was use useEffect hook after return statement which as cause this error
if (isLoading) {
return
}
if (error) {
return
}
At here
useEffect(() => {
console.log("isEdit: ",isEdit);
if (isEdit) {
setFormData({
subject: editData?.subject,
message: editData?.message,
})
}
}, [isEdit])