Cannot rewrite the title as it is already explicit and clear
P粉253518620
2023-08-15 18:38:17
<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>
and
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.
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.