無法重寫標題,因為標題已經很明確和清晰了
P粉253518620
2023-08-15 18:38:17
<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<string[]>([]);
const renderItem = useCallback(
({ item }: ListRenderItemInfo<Todo>) => (
<TouchableOpacity
style={{ height: 50 }}
onPress={() => {
console.log(todos.length); // 總是記錄0。
if (todos.length >= 10) return;
setTodos((curr) => [item.name, ...curr]);
}}
>
<Heading color={"black"}>{item.name}</Heading>
</TouchableOpacity>
),
[]
);
return (
<FlashList<Todo>
data={data?.todos as Todo[]}
estimatedItemSize={50}
renderItem={renderItem}
keyExtractor={(_, idx) => idx.toString()}
/>
);
}</pre>
<p>注意:我嘗試將<code>todos</code>和<code>todos.length</code>都作為依賴項傳遞給<code>useCallback</code>,但結果是相同的。 </p>
<p>樂意解答任何問題。 </p>
和
這是一個常見的問題,因為它不明顯。因為這種情況經常發生,所以
setState
有一個回調版本。在你的程式碼中,你實際上是使用它來設定狀態,但你還需要使用它來取得當前狀態以進行最大10個的檢查。所以一個簡單的解決方法是將長度檢查放在useState的回呼函數中。
在上面的程式碼中,如果目前長度大於或等於10,則只傳回目前狀態,否則新增項目。
另一個選項,當然將todos添加到useCallback的狀態中,但為什麼這在
FlashList
中不起作用,不確定。更好的選擇是將
Item
提取為另一個子元件。這樣做還有其他好處,例如更多的組合性、程式碼共享,最重要的是效能。