简体   繁体   English

在循环内渲染和返回

[英]Render and return inside a loop

In my code, I call a function showUsers .在我的代码中,我调用了 function showUsers This function displays all the users in a styled box.此 function 在样式框中显示所有用户。 For now, the numberOfUsers passed into it is 1, as confirmed by console.logs as well.目前,传递给它的numberOfUsers为 1,console.logs 也证实了这一点。

So the loop should only runs once.所以循环应该只运行一次。 However, all these console.logs are repeated twice.但是,所有这些 console.logs 都会重复两次。 The output values remain the same. output 值保持不变。 Why is this so?为什么会这样?

         console.log('Number of Users in Loop: ', numberOfUsers);
         console.log('Whats the Id', userId);
         console.log('UserName', userName);
         console.log('i: ', i);

Code:代码:

export const Page: React.FunctionComponent<PageProps> = ({
  toggleShowPage,
  showAddFriendEmailPage,
}) => {
  const initialValues: FormValues = {
    email: '',
  };

  const [errorMessage, setErrorMessage] = useState('');
  const [userData, setUserData] = useState<UsersLazyQueryHookResult>('');
  const [numberOfUsers, setNumberOfUsers] = useState('');
  const validationSchema = emailValidationSchema;

  useEffect(() => {
    setUserData(userData);
    setNumberOfUsers(numberOfUsers);
  }, [userData, numberOfUsers]);


  const showAlert = () => {
    Alert.alert('Friend Added');
  };

  useEffect(() => {
    if (showAddFriendEmailPage) return;
    initialValues.email = '';
  }, [showAddFriendEmailPage]);

  const _onLoadUserError = React.useCallback((error: ApolloError) => {
    setErrorMessage(error.message);
    Alert.alert('Unable to Add Friend');
  }, []);

  const [
    createUserRelationMutation,
    {
      data: addingFriendData,
      loading: addingFriendLoading,
      error: addingFriendError,
      called: isMutationCalled,
    },
  ] = useCreateUserRelationMutation({
    onCompleted: (data: CreateUserRelationMutationResult) => {
      showAlert();
    },
  });

   const showUsers = React.useCallback(
     (data: UsersLazyQueryHookResult, numberOfUsers: Number) => {
       for (var i = 0; i < numberOfUsers; i++) {
        console.log('Number of Users in Loop: ', numberOfUsers);
         const userId = data.users.nodes[i].id;
         const userName = ((data.users.nodes[i].firstName).concat(' ')).concat(data.users.nodes[i].lastName);
         console.log('Whats the Id', userId);
         console.log('UserName', userName);
         console.log('Loop');
         return(
           <View style={styles.friends}>
             <View style={styles.item}>
              <Text>{userName}</Text>
             </View>
           </View>
         )
       }      
     },
     [createUserRelationMutation],
   );

  const addFriend = React.useCallback(
    (id: Number) => {
      console.log('Whats the Id', id);
      createUserRelationMutation({
        variables: {
          input: { relatedUserId: id, type: RelationType.Friend, userId: 7 },
        },
      });
    },
    [createUserRelationMutation],
  );

  const getFriendId = React.useCallback(
    (data: UsersLazyQueryHookResult) => {
      if (data) {
        if (data.users.nodes.length == 0) {
          setErrorMessage('User Not Found');
          Alert.alert('User Not Found');
        } else {
          setUserData(data);
          setNumberOfUsers(data.users.nodes.length);
          //showUsers(data, Number(numberOfUsers));
          addFriend(Number(data.users.nodes[0].id));
        }
      }
    },
    [addFriend],
  );

  const [loadUsers] = useUsersLazyQuery({
    onCompleted: getFriendId,
    onError: _onLoadUserError,
  });

  const handleSubmitForm = React.useCallback(
    (values: FormValues, helpers: FormikHelpers<FormValues>) => {
      console.log('Submitted');
      loadUsers({
        variables: {
          where: { email: values.email },
        },
      });
      values.email = '';
    },
    [loadUsers],
  );

  return (
    <Modal
      visible={showAddFriendEmailPage}
      animationType="slide"
      transparent={true}>
      <SafeAreaView>
        <View style={styles.container}>
          <View style={styles.searchTopContainer}>
              <Formik
                initialValues={initialValues}
                onSubmit={handleSubmitForm}
                validationSchema={validationSchema}>
                {({ handleChange, handleBlur, handleSubmit, values }) => (
                  <View style={styles.searchFieldContainer}>
                    <View style={styles.form}>
                      <FieldInput
                        handleChange={handleChange}
                        handleBlur={handleBlur}
                        value={values.email}
                        fieldType="email"
                      />
                      <ErrorMessage
                        name="email"
                        render={msg => (
                          <Text style={styles.errorText}>{msg}</Text>
                        )}
                      />
                    </View>
                    <View style={styles.buttonContainer}>
                      <Button
                        rounded
                        style={styles.button}
                        onPress={handleSubmit}>
                        <Text style={styles.text}>Add Friend </Text>
                      </Button>
                    </View>
                  </View>
                )}
              </Formik>
            </View>
            {showUsers(userData, Number(numberOfUsers))}
          </View>
        </View>
      </SafeAreaView>
    </Modal>
  );
};

UPDATED CODE:更新代码:

export const Page: React.FunctionComponent<PageProps> = ({
  toggleShowPage,
  showAddFriendEmailPage,
}) => {
  const initialValues: FormValues = {
    email: '',
  };

  const [errorMessage, setErrorMessage] = useState('');
  const [isSubmitted, setIsSubmitted] = useState(false);
  const [userData, setUserData] = useState<UsersLazyQueryHookResult>('');
  const [numberOfUsers, setNumberOfUsers] = useState('');

  const validationSchema = emailValidationSchema;

   const showUsers = React.useCallback(
     (data: UsersLazyQueryHookResult, numberOfUsers: Number) => {
      if (data){
       for (var i = 0; i < numberOfUsers; i++) {
         console.log('Number of Users in Loop: ', numberOfUsers);
         const userId = data.users.nodes[i].id;
         const userName = data.users.nodes[i].firstName
           .concat(' ')
           .concat(data.users.nodes[i].lastName);
         return (
           <View style={styles.friends}>
             <View style={styles.item}>
               <Text style={styles.userName}>{userName}</Text>
               <View style={styles.addButtonContainer}>
                 <Button
                   onPress={() => {
                     addFriend(Number(data.users.nodes[i].id));
                     setIsSubmitted(false);
                   }}>
                 </Button>
               </View>
             </View>
           </View>
         );
       }}
     },
     [createUserRelationMutation, userData, numberOfUsers],
   );

  const addFriend = React.useCallback(
    (id: Number) => {
      console.log('Whats the Id', id);
      createUserRelationMutation({
        variables: {
          input: { relatedUserId: id, type: RelationType.Friend, userId: 7 },
        },
      });
    },
    [createUserRelationMutation],
  );

  const getFriendId = React.useCallback(
    (data: UsersLazyQueryHookResult) => {
      if (data) {
        if (data.users.nodes.length == 0) {
          setErrorMessage('User Not Found');
          Alert.alert('User Not Found');
        } else {
          setUserData(data);
          setNumberOfUsers(data.users.nodes.length);
        }
      }
    },
    [addFriend],
  );



  const [loadUsers] = useUsersLazyQuery({
    onCompleted: getFriendId,
    onError: _onLoadUserError,
  });

  const handleSubmitForm = React.useCallback(

    (values: FormValues, helpers: FormikHelpers<FormValues>) => {
      setIsSubmitted(true);
      console.log('Submitted');
      loadUsers({
        variables: {
          where: { email: values.email },
        },
      });
      values.email = '';
    },
    [loadUsers],
  );


  if (!addingFriendLoading && isMutationCalled) {
    if (addingFriendError) {
      setErrorMessage(addingFriendError.message);
      Alert.alert('Unable to Add Friend');
    }
  }

  return (
    <Modal
      visible={showAddFriendEmailPage}
      animationType="slide"
      transparent={true}>
      <SafeAreaView>
        <View style={styles.container}>
          <View style={styles.searchTopContainer}>
            <View style={styles.searchTopTextContainer}>
              <Text
                style={styles.searchCancelDoneText}
                onPress={() => {
                 toggleShowPage()
                  setIsSubmitted(false);
                  setUserData(null);
              }}
              >
                Cancel
              </Text>
              <Text style={styles.searchTopMiddleText}>
                Add Friend by Email
              </Text>
              <Text style={styles.searchCancelDoneText}>Done</Text>
            </View>
            <View>
              <Formik
                initialValues={initialValues}
                onSubmit={handleSubmitForm}
                validationSchema={validationSchema}>
                {({ handleChange, handleBlur, handleSubmit, values }) => (
                  <View style={styles.searchFieldContainer}>
                    <View style={styles.form}>
                      <FieldInput
                        handleChange={handleChange}
                        handleBlur={handleBlur}
                        value={values.email}
                        fieldType="email"
                      />
                      <ErrorMessage
                        name="email"
                        render={msg => (
                          <Text style={styles.errorText}>{msg}</Text>
                        )}
                      />
                    </View>
                    <View style={styles.buttonContainer}>
                      <Button
                        rounded
                        style={styles.button}
                        onPress={handleSubmit}>
                        <Text style={styles.text}>Search </Text>
                      </Button>
                    </View>
                  </View>
                )}
              </Formik>
            </View>
            {isSubmitted && showUsers(userData, Number(numberOfUsers))}    
          </View>
        </View>
      </SafeAreaView>
    </Modal>
  );
};

You are also calling setUserData from getFriendId , so it will update userData您还从getFriendId调用setUserData ,因此它将更新userData

const getFriendId = React.useCallback(
    ....
    setUserData(data);

So it will invoke render and useEffect所以它会调用renderuseEffect

useEffect(() => {
    setUserData(userData);
    setNumberOfUsers(numberOfUsers);
}, [userData, numberOfUsers]);

You can comment out useEffect and check no of console.log您可以注释掉useEffect并检查console.log的 no

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM