搜尋

首頁  >  問答  >  主體

無法重寫標題,因為標題已經很明確和清晰了

<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>
P粉253518620P粉253518620455 天前398

全部回覆(1)我來回復

  • P粉805922437

    P粉8059224372023-08-16 15:36:35

    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提取為另一個子元件。這樣做還有其他好處,例如更多的組合性、程式碼共享,最重要的是效能。

    回覆
    0
  • 取消回覆