React Native scrollview 无限重新渲染
React Native scrollview infinitely rerendering
我是 React Native 的新手,我正在创建一个待办事项列表应用程序。当我将 Todos 状态初始化为非空数组时,我编写的组件会无限重新渲染。这会导致反应停止的错误。我不知道是什么导致了无限循环,因为我没有包含任何递归或显式循环。我在各处添加了一些 console.log(),发现 deleteTodo 和 toggleTodo 一直被自动调用,直到应用程序崩溃。
当 Todos 状态初始化为一个空数组时,我收到一条错误消息,指出 getTodos.map 不是一个函数。
只有当状态更新为修改、添加或删除任务时,组件才会重新呈现。
import React, { useState } from 'react'
import { Platform, StyleSheet, Text, View, TouchableHighlight } from 'react-native'
import { State, ScrollView } from 'react-native-gesture-handler'
/* All required imports are correctly added */
let id = 0
function TaskRow(props) {
return (
<View>
{/* empty button acting as checkbox */}
<TouchableHighlight>
<Text />
</TouchableHighlight>
{/* main text area, displays task and all details + tags*/}
<TouchableHighlight onPress={props.toggle(props.key)}>
<Text>{props.task}</Text>
</TouchableHighlight>
{/* delete button */}
<TouchableHighlight onPress={props.delete(props.key)}>
<Text>Delete</Text>
</TouchableHighlight>
</View>
)
}
export default function TodoList() {
const [
getTodos,
setTodos,
] = useState([
{ key: id, task: 'this is a task', checked: false },
])
const addTodo = (taskInput = 'sample') => {
id++
setTodos(getTodos.push({ key: id, task: 'task', checked: false }))
}
const deleteTodo = (deleteID) => {
setTodos(getTodos.filter((match) => match.key !== deleteID))
}
const toggleTodo = (toggleID) => {
setTodos(
getTodos.map((match) => {
if (match.key == toggleID) return { key: match.key, task: match.task, checked: !match.checked }
}),
)
}
return (
<View>
<TouchableHighlight onPress={addTodo}>
<Text>Add task</Text>
</TouchableHighlight>
<ScrollView>
{getTodos.map((task) => (
<TaskRow
key={task.key}
task={task.task}
delete={deleteTodo}
toggle={toggleTodo}
/>
))}
</ScrollView>
</View>
)
}
您的 TaskRow
组件存在问题,在每次渲染时您实际上是在调用函数而不是声明事件处理程序。请这样写这两行:
// ...
<TouchableHighlight onPress={() => props.toggle(props.key)}>
// ...
<TouchableHighlight onPress={() => props.delete(props.key)}>
另一个问题是:
setTodos(getTodos.push({ key: id, task: 'task', checked: false }))
.push()
没有 return 数组,所以你应该这样做:
setTodos([...getTodos, { key: id, task: 'task', checked: false }])
我是 React Native 的新手,我正在创建一个待办事项列表应用程序。当我将 Todos 状态初始化为非空数组时,我编写的组件会无限重新渲染。这会导致反应停止的错误。我不知道是什么导致了无限循环,因为我没有包含任何递归或显式循环。我在各处添加了一些 console.log(),发现 deleteTodo 和 toggleTodo 一直被自动调用,直到应用程序崩溃。
当 Todos 状态初始化为一个空数组时,我收到一条错误消息,指出 getTodos.map 不是一个函数。
只有当状态更新为修改、添加或删除任务时,组件才会重新呈现。
import React, { useState } from 'react'
import { Platform, StyleSheet, Text, View, TouchableHighlight } from 'react-native'
import { State, ScrollView } from 'react-native-gesture-handler'
/* All required imports are correctly added */
let id = 0
function TaskRow(props) {
return (
<View>
{/* empty button acting as checkbox */}
<TouchableHighlight>
<Text />
</TouchableHighlight>
{/* main text area, displays task and all details + tags*/}
<TouchableHighlight onPress={props.toggle(props.key)}>
<Text>{props.task}</Text>
</TouchableHighlight>
{/* delete button */}
<TouchableHighlight onPress={props.delete(props.key)}>
<Text>Delete</Text>
</TouchableHighlight>
</View>
)
}
export default function TodoList() {
const [
getTodos,
setTodos,
] = useState([
{ key: id, task: 'this is a task', checked: false },
])
const addTodo = (taskInput = 'sample') => {
id++
setTodos(getTodos.push({ key: id, task: 'task', checked: false }))
}
const deleteTodo = (deleteID) => {
setTodos(getTodos.filter((match) => match.key !== deleteID))
}
const toggleTodo = (toggleID) => {
setTodos(
getTodos.map((match) => {
if (match.key == toggleID) return { key: match.key, task: match.task, checked: !match.checked }
}),
)
}
return (
<View>
<TouchableHighlight onPress={addTodo}>
<Text>Add task</Text>
</TouchableHighlight>
<ScrollView>
{getTodos.map((task) => (
<TaskRow
key={task.key}
task={task.task}
delete={deleteTodo}
toggle={toggleTodo}
/>
))}
</ScrollView>
</View>
)
}
您的 TaskRow
组件存在问题,在每次渲染时您实际上是在调用函数而不是声明事件处理程序。请这样写这两行:
// ...
<TouchableHighlight onPress={() => props.toggle(props.key)}>
// ...
<TouchableHighlight onPress={() => props.delete(props.key)}>
另一个问题是:
setTodos(getTodos.push({ key: id, task: 'task', checked: false }))
.push()
没有 return 数组,所以你应该这样做:
setTodos([...getTodos, { key: id, task: 'task', checked: false }])