Cannot rewrite the title as it is already explicit and clear
P粉253518620
P粉253518620 2023-08-15 18:38:17
0
1
413
<p>I'm using Flashlist in React Native and I'm using the <code>useCallback</code> hook in my <code>renderItem</code> function. In my component I have a state (an array) called <code>todos</code> and when I log <code>todos.length</code> I only get the initial state value 0. Why is this happening and how do I fix it? </p> <pre class="brush:php;toolbar:false;">export default function MyComponent() { // Some code has been omitted for brevity. const [todos, setTodos] = useState<string[]>([]); const renderItem = useCallback( ({ item }: ListRenderItemInfo<Todo>) => ( <TouchableOpacity style={{ height: 50 }} onPress={() => { console.log(todos.length); // Always log 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>Note: I tried passing both <code>todos</code> and <code>todos.length</code> as dependencies to <code>useCallback</code> but the result was the same of. </p> <p>Happy to answer any questions. </p>
P粉253518620
P粉253518620

reply all(1)
P粉805922437
const [todos, setTodos] = useState<string[]>([]);

and

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

This is a common problem because it's not obvious. Because this happens often, setState has a callback version. In your code you are actually using it to set the state, but you also need to use it to get the current state for a maximum of 10 checks.

So a simple solution is to put the length check in the callback function of useState.

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

In the above code, if the current length is greater than or equal to 10, only the current status is returned, otherwise a new item is added.

Another option, of course, is to add todos to useCallback's state, but why this doesn't work in FlashList, not sure.

A better option is to extract Item as another child component. There are other benefits to doing this, such as more composability, code sharing, and most importantly, performance.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template