簡體   English   中英

React Native - 如何從父組件調用子組件的 function(不觸發無限循環)?

[英]React Native - how do you call the function of a child component from its parent (without triggering an infinite loop)?

我正在嘗試創建一個顯示特色產品的 React Native 電子商務應用程序,但隨后用戶可以通過從底部彈出的工作表查看類別列表,這將加載所述類別中的產品。

我已經設法使用 react-native-btr 的 BottomSheet 創建了這樣一個底部表。 但是,用於顯示/隱藏組件的 function(只需切換狀態中的 boolean)需要組件本身可用(以處理后退按鈕和背景按下)。

這是組件代碼:

const TestNav = (props, ref) => {
  const [visible, setVisible] = useState(false);

  const toggleVisible = () => {
    setVisible(!visible);
  };

  useImperativeHandle(ref, () => toggleVisible());

  return (
    <BottomSheet
      visible={visible}
      //setting the visibility state of the bottom shee
      onBackButtonPress={toggleVisible}
      //Toggling the visibility state on the click of the back botton
      onBackdropPress={toggleVisible}
      //Toggling the visibility state on the clicking out side of the sheet
    >
      <View style={styles.bottomNavigationView}>
        <View
          style={{
            flex: 1,
            flexDirection: 'column',
          }}
        >
          {DummyData.map((item) => {
            return (
              <Button
                key={item.id}
                title={item.name}
                type="clear"
                buttonStyle={styles.button}
                onPress={() => console.log(item.name)}
              />
            );
          })}
        </View>
      </View>
    </BottomSheet>
  );
};
export default React.forwardRef(TestNav);

這是使用它的屏幕的代碼(它被稱為 ChatScreen,因為我將它用作測試場,因為我還沒有實現該功能)

import React, { useRef } from 'react';
import {SafeAreaView,StyleSheet,View,Text} from 'react-native';
import TestNav from '../components/TestNav';
import { Button } from 'react-native-elements';

const ChatScreen = () => {
  const childRef = useRef(null);

  const toggleBottomNavigationView = () => {
    if (myRef.current) {
      childRef.current.toggleVisible;
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.container}>
        <Text
          style={{
            fontSize: 20,
            marginBottom: 20,
            textAlign: 'center',
          }}
        >
          Content goes here
        </Text>
        <Button
          onPress={() => toggleBottomNavigationView()}
          title="Show Bottom Sheet"
        />
        <TestNav ref={childRef} />
      </View>
    </SafeAreaView>
  );
};
export default ChatScreen;

但是,當我收到此消息時,此代碼以某種方式觸發了無限循環:

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

我如何解決這個問題 go?

我認為問題在於您如何定義命令句柄。 每次組件渲染時都會調用掛鈎回調,因此每次渲染都會調用() => toggleVisible()並創建渲染循環。 應該向它傳遞一個回調,該回調返回要提供給被調用者的命令式函數/值。

const toggleVisible = () => {
  setVisible(visible => !visible);
};

useImperativeHandle(ref, () => ({
  toggleVisible,
}));

然后,在ChatScreen中,您需要調用 function。我假設您的代碼段中的myRef是一個拼寫錯誤,因為它沒有在組件中聲明,並且用法似乎類似於保護模式。

const toggleBottomNavigationView = () => {
  childRef.current && childRef.current.toggleVisible();
  // or childRef.current?.toggleVisible();
};

我正在嘗試創建一個 React Native 電子商務應用程序,其中顯示特色產品,但隨后用戶可以通過從底部彈出的工作表查看類別列表,該工作表將從所述類別加載產品。

我已經設法使用 react-native-btr 的 BottomSheet 創建了這樣的底部表。 但是,function 顯示/隱藏組件(只需在狀態下切換 boolean)需要對組件本身可用(以處理后退按鈕和背景按下)。

這是組件代碼:

const TestNav = (props, ref) => {
  const [visible, setVisible] = useState(false);

  const toggleVisible = () => {
    setVisible(!visible);
  };

  useImperativeHandle(ref, () => toggleVisible());

  return (
    <BottomSheet
      visible={visible}
      //setting the visibility state of the bottom shee
      onBackButtonPress={toggleVisible}
      //Toggling the visibility state on the click of the back botton
      onBackdropPress={toggleVisible}
      //Toggling the visibility state on the clicking out side of the sheet
    >
      <View style={styles.bottomNavigationView}>
        <View
          style={{
            flex: 1,
            flexDirection: 'column',
          }}
        >
          {DummyData.map((item) => {
            return (
              <Button
                key={item.id}
                title={item.name}
                type="clear"
                buttonStyle={styles.button}
                onPress={() => console.log(item.name)}
              />
            );
          })}
        </View>
      </View>
    </BottomSheet>
  );
};
export default React.forwardRef(TestNav);

這是正在使用它的屏幕的代碼(它被稱為 ChatScreen,因為我將它用作測試場,因為我還沒有實現該功能)

import React, { useRef } from 'react';
import {SafeAreaView,StyleSheet,View,Text} from 'react-native';
import TestNav from '../components/TestNav';
import { Button } from 'react-native-elements';

const ChatScreen = () => {
  const childRef = useRef(null);

  const toggleBottomNavigationView = () => {
    if (myRef.current) {
      childRef.current.toggleVisible;
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.container}>
        <Text
          style={{
            fontSize: 20,
            marginBottom: 20,
            textAlign: 'center',
          }}
        >
          Content goes here
        </Text>
        <Button
          onPress={() => toggleBottomNavigationView()}
          title="Show Bottom Sheet"
        />
        <TestNav ref={childRef} />
      </View>
    </SafeAreaView>
  );
};
export default ChatScreen;

但是,當我收到此消息時,此代碼以某種方式觸發了無限循環:

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

我該如何解決這個問題?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM