【问题标题】:React Native useState prevent rerendering flatlistReact Native useState 防止重新渲染平面列表
【发布时间】:2021-09-19 20:25:47
【问题描述】:

所以我有一个 React Native Flatlist。然后我有一个 useState,当我点击我的平面列表中的一个项目时会触发它。我现在面临的问题是,如果我单击一个项目并且 useState() 触发 每个 项目将重新呈现。这很糟糕,因为它使应用程序异常缓慢。

有没有什么方法可以设置我的状态而不重新渲染 FlatList 但出现另一个视图(因为 useState())??

我的代码如下所示:

import React, {useState} from "react"
import {View, Flatlist, Text} from "react-native"

export default const App = () => {

  const [x, setX] = useState(false)

  return(
    <View>
      <FlatList
        data = {
          ["-",
          "--",
          "---",
          "----",
          "-----",
          "------",
          "-------",
          "--------",
          "---------"]
        }
        renderItem={({item}) => {(
          <View>
            <TouchableOpacity onPress={() => setX(true)}>
              <Text style={{padding: 10,}}>{item}</Text>
            </TouchableOpacity>
          </View>
        )}}
      />
      {x == true ? <Button title="It works" onPress={() => console.log("Everything is working")} /> : <View />}
    </View>
)
}

在此示例中,数据列表非常小。如果它变得更大,你真的可以看到不同

【问题讨论】:

    标签: javascript reactjs react-native


    【解决方案1】:

    为了确保FlatList 不会在状态更改时重新呈现(参见下面的代码),需要考虑以下事项:

    1. 确保传递的data 以某种方式存储或记忆。
    2. 确保回调也被记忆。
    import React, {useState} from "react"
    import {View, Flatlist, Text} from "react-native"
    
    export default const App = () => {
      // See 1. above
      const [data, setData] = useState([
        "-",
        "--",
        "---",
        "----",
        "-----",
        "------",
        "-------",
        "--------",
        "---------",
      ]);
      const [x, setX] = useState(false)
    
      // See 2. above
      const renderItem = useCallback(({ item }) => (
        <View>
          <TouchableOpacity onPress={() => setX(true)}>
            <Text style={{padding: 10,}}>{item}</Text>
          </TouchableOpacity>
        </View>
      ), []);
    
      return(
        <View>
          <FlatList
            data={data}
            renderItem={renderItem}
          />
          {x == true ? <Button title="It works" onPress={() => console.log("Everything is working")} /> : <View />}
        </View>
    )
    }
    

    【讨论】:

    • 奖励将是一个状态初始化器 - useState(() =&gt; data) 如果data 真的很大。
    • 假设我也有const [y, setY] = useState(false)。如果 y 更改值但只有在 y 更改值而不是 x 时,有什么方法可以使 Flatlist 重新呈现?
    • @Henrik,是的。您可以将y 数据传递给FlatListextraData 道具
    • 非常感谢:)
    【解决方案2】:

    这是一个带有备忘录和单独组件的想法:

    const App = () => {
      const [x,setX] = useState(false);
    
      return (
        <View>
          <MyFlatList setX={setX}/>
          {x == true ? <Button title="It works" onPress={() => console.log("Everything is working")} /> : <View />}
        </View>
      )
    }
    

    然后:

    const MyFlatList = React.memo(({setX}) => {
      return (
          <FlatList
            data = {
              ["-",
              "--",
              "---",
              "----",
              "-----",
              "------",
              "-------",
              "--------",
              "---------"]
            }
            renderItem={({item}) => {(
              <View>
                <TouchableOpacity onPress={() => setX(true)}>
                  <Text style={{padding: 10,}}>{item}</Text>
                </TouchableOpacity>
              </View>
            )}}
          />
      );
    });
    

    爬虫的回答非常好,建议记住数据和回调。

    【讨论】:

    • 谢谢。我接受了爬虫消息:)
    猜你喜欢
    • 2021-01-07
    • 2020-01-04
    • 2020-03-17
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 2021-05-03
    • 2021-12-10
    • 2021-10-21
    相关资源
    最近更新 更多