【问题标题】:How to stop Array from constantly re-rendering如何阻止 Array 不断重新渲染
【发布时间】:2021-09-16 12:50:15
【问题描述】:

我有一个图像数组,当我单击反应中的按钮并选择图像时,我正在更新每个值。但是,当我只希望在选择图像时,数组会不断重新渲染。 这是我的代码:

   function OnboardingUploadPhotos() {
  const [modalVisible, setModalVisible] = useState(false);
  const [permissionStatus, setPermissionStatus] = useState('');
  const [files, setFiles] = useState<string[]>([]);
  const [fileArray, setFileArray] = useState<string[]>(['', '', '', '', '', '', '']);

  const setPermissions = useCallback(val => {
    setPermissionStatus(val);
  }, [setPermissionStatus]);

  const setIsModalVisible = useCallback(val => {
    setModalVisible(val);
  }, [setModalVisible]);

  async function fetchAssets() {
    const recentCameraRoll = await MediaLibrary.getAssetsAsync({first: 11});
    setFiles(recentCameraRoll.assets.slice(1).map(file => file.uri));
  }

  function replaceFileState(file: string, index: number) {
    let f = [...fileArray];
    f[index] = file;
    setFileArray(f);
  }

  useEffect(() => {
    fetchAssets();
  }, [fetchAssets]);

  return (
      <View>
        {permissionStatus ?
            <Modal style={styles.bottomModalView} isVisible={modalVisible} backdropOpacity={0}
                   onBackdropPress={() => setModalVisible(false)}>
              <View style={styles.modal}>
                <TouchableOpacity>
                  <Text style={{
                    borderBottomWidth: 1,
                    borderBottomColor: '#FFF',
                    color: '#FFF',
                    textDecorationLine: 'underline',
                    alignSelf: 'flex-end',
                    justifyContent: 'center',
                    paddingTop: 40
                  }}>All photos</Text>
                </TouchableOpacity>
                <ScrollView horizontal={true} scrollEnabled={true}
                            contentContainerStyle={{justifyContent: 'center', alignItems: 'center'}}>
                  {files.map((file, index) => {
                    return (
                        <TouchableWithoutFeedback key={index} onPress={() => replaceFileState(file, index)}>
                          <Image
                              key={file}
                              style={{width: 100, height: 100, marginLeft: 10, marginRight: 10, borderRadius: 4}}
                              source={{uri: file}}
                          />
                        </TouchableWithoutFeedback>
                    );
                  })}
                </ScrollView>
                <Text style={{fontSize: 22, color: '#FFF', marginLeft: 20, marginBottom: 20}}>Your photos</Text>
              </View>
            </Modal> :
            null
        }
        <Text>Upload your photos</Text>
        <View style={{flexDirection: "row", flexWrap: "wrap", justifyContent: 'space-evenly'}}>
          {fileArray.slice(0,6).map((image, index) => {
            console.log(fileArray)
            return (
                image != '' ?
                    <Image
                        key={image}
                        style={{width: 100, height: 100, borderRadius: 100}}
                        source={{uri: image}}
                    /> :
                    <OnboardingPhoto key={index} setStatus={setPermissions} setModal={setIsModalVisible}/>
            )
          })}
        </View>
      </View>
  );
}

这是一个包含所有用户最新图像的模式,点击每个图像时,它会用屏幕上的用户图像替换空的占位符图像。然而,它不断地重新渲染。我说把它放在useEffect 但我不知道在哪里!任何帮助都会很棒,谢谢!

【问题讨论】:

    标签: javascript reactjs typescript react-native


    【解决方案1】:

    我认为您需要在TouchableWithoutFeedback 组件上定义一个key 属性。

    在此处查看指南:https://reactjs.org/docs/lists-and-keys.html

    【讨论】:

    • TouchableOpacity 扩展 TouchableWithoutFeedback 的 props 时,这是否相同?
    • 这也有效并停止照片重新渲染,但我有一个 console.log(fileArray) 仍然每次都重新渲染?
    • 这就是 React 的工作原理。您的 console.log 语句放在哪里? React 会多次调用你的组件,但不一定会导致新的渲染。 “Key”允许 React 查看是否发生了变化。
    • 啊,是的,它就在我的 jsx 返回函数之外。我从来不知道Key到底做了什么!谢谢!
    • 您将 Image 元素的 key 属性设置为图像本身。那是行不通的。改用索引。事实上,也不要这样做 - 改用 image-${index} 之类的东西,这样您的键就不会与 TouchableWithoutFeedback 键发生冲突。所有键都必须是唯一的。
    【解决方案2】:

    Hooks 被用于函数组件内部,这可能是原因之一。

    【讨论】:

    • 我解决了我最初的问题,但我的工作现在不断地重新渲染!有什么想法吗?
    猜你喜欢
    • 2020-07-06
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多