无法重写标题,因为标题已经很明确和清晰了
P粉253518620
P粉253518620 2023-08-15 18:38:17
[React讨论组]
<p>我正在使用React Native中的Flashlist,并且在我的<code>renderItem</code>函数中使用了<code>useCallback</code> hook。在我的组件中,我有一个状态(一个数组)叫做<code>todos</code>,当我记录<code>todos.length</code>时,我只得到初始状态值0。为什么会这样,我该如何修复?</p> <pre class="brush:php;toolbar:false;">export default function MyComponent() { // 为了简洁起见,省略了一些代码。 const [todos, setTodos] = useState&lt;string[]&gt;([]); const renderItem = useCallback( ({ item }: ListRenderItemInfo&lt;Todo&gt;) =&gt; ( &lt;TouchableOpacity style={{ height: 50 }} onPress={() =&gt; { console.log(todos.length); // 总是记录0。 if (todos.length &gt;= 10) return; setTodos((curr) =&gt; [item.name, ...curr]); }} &gt; &lt;Heading color={"black"}&gt;{item.name}&lt;/Heading&gt; &lt;/TouchableOpacity&gt; ), [] ); return ( &lt;FlashList&lt;Todo&gt; data={data?.todos as Todo[]} estimatedItemSize={50} renderItem={renderItem} keyExtractor={(_, idx) =&gt; idx.toString()} /&gt; ); }</pre> <p>注意:我尝试将<code>todos</code>和<code>todos.length</code>都作为依赖项传递给<code>useCallback</code>,但结果是相同的。</p> <p>乐意解答任何问题。</p>
P粉253518620
P粉253518620

全部回复(1)
P粉805922437
const [todos, setTodos] = useState<string[]>([]);

const renderItem = useCallback(
  () => {
    //todo's here is a closure, it will not update
    //a dependency of [] means, just run once.
  },
  []
);

这是一个常见的问题,因为它不明显。因为这种情况经常发生,所以setState有一个回调版本。在你的代码中,你实际上是使用它来设置状态,但你还需要使用它来获取当前状态以进行最大10个的检查。

所以一个简单的解决方法是将长度检查放在useState的回调函数中。

setTodos((curr) => curr.length >= 10 ? curr : [item.name, ...curr]);

在上面的代码中,如果当前长度大于或等于10,只返回当前状态,否则添加新项目。

另一个选项,当然是将todos添加到useCallback的状态中,但为什么这在FlashList中不起作用,不确定。

更好的选择是将Item提取为另一个子组件。这样做还有其他好处,比如更多的组合性、代码共享,最重要的是性能。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号