You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中父组件传递数组给子组件后如何更新并触发重渲染

问题根因

你的代码存在两处核心问题导致新增任务不生效:

  • HomeScreen中存储任务数组的taskList是普通JS变量,没有通过useState托管为响应式状态:你直接调用push修改数组的操作React无法感知,不会触发HomeScreen重渲染,传递给ItemList的listprop永远是初始值。
  • ItemList中将传入的props.list复制到了本地state中:useState的初始值仅在组件首次挂载时生效,后续父组件传递的listprop发生变化时,子组件的本地state不会自动同步,因此视图不会更新。

你之前的勾选、删除功能可以正常生效,是因为这两个操作修改的是ItemList自身的本地state,能直接触发子组件重渲染,没有涉及父子组件的数据同步。

修复方案

推荐采用状态提升的最佳实践:所有任务数据的修改逻辑统一在HomeScreen中维护,ItemList仅作为纯展示组件接收参数、触发回调,不维护独立的本地状态,避免多组件存储同一份数据导致的同步问题。

1. 修改HomeScreen.jsx

将taskList改为响应式状态,新增修改数据的方法传递给子组件:

import React, { useEffect, useState } from 'react'
import {
  SafeAreaView,
  StyleSheet,
  StatusBar
} from 'react-native'

import Task from '../Components/modelItem'
import ItemList from '../Components/ItemList'
import FloatButton from '../Components/FloatButton'

const HomeScreen = ({ navigation, route }) => {
  // 将taskList改为响应式状态
  const [taskList, setTaskList] = useState([
    new Task(1, '示例', '示例任务', new Date(),
      new Date("2021-10-21")),
    new Task(2, 'RN TODO', '开发待办应用', new Date(),
      new Date("2021-11-18")),
    new Task(3, '待办', '完成某项工作', new Date(),
      new Date("2021-11-25")),
  ])

  console.log(route.params)

  useEffect(() => {
    if (route.params?.description) {
      console.log('useEffect:')
      console.log(route.params)
      // 用setTaskList更新状态,生成新数组触发重渲染
      setTaskList(prevList => [...prevList, new Task(
        Date.now(), // 生成唯一ID,不能传null
        '测试任务', 
        route.params.description,
        route.params.creationDate, 
        route.params.expireDate
      )])
    }
  }, [route.params?.description])

  // 勾选任务回调
  const handleCheckTask = (taskId, isChecked) => {
    setTaskList(prevList => {
      const elem = prevList.find(x => x.id === taskId)
      elem.isDone = isChecked
      const newList = prevList.filter(x => x.id !== taskId)
      isChecked ? newList.push(elem) : newList.unshift(elem)
      return newList
    })
  }

  // 删除任务回调
  const handleDeleteTask = (taskId) => {
    setTaskList(prevList => prevList.filter(x => x.id !== taskId))
  }

  return (
    <SafeAreaView style={styles}>
      <ItemList
        list={taskList}
        onCheckTask={handleCheckTask}
        onDeleteTask={handleDeleteTask}
      />
      <FloatButton onPress={() => navigation.navigate('AddNewTask')} />
    </SafeAreaView>
  )
}

const styles = StyleSheet.create({
  flex: 1,
  marginTop: StatusBar.currentHeight || 0,
})

export default HomeScreen

2. 修改ItemList.jsx

删除本地state,直接使用props传入的数据和回调:

import React from 'react'
import { FlatList } from 'react-native-gesture-handler'
import { Text } from 'react-native'

import Item from './Item'

const ItemList = (props) => {
  const itemRender = ({ item }) => {
    // 复选框处理函数直接调用父组件回调
    const checkBoxHandler = (isChecked) => {
      props.onCheckTask(item.id, isChecked)
    }

    // 计算截止时间剩余时长的逻辑保留
    const calculateDeadline = () => {
      var deltaTime = item.expireDate - new Date()
      var deltaDays = Math.ceil(deltaTime / (1000 * 60 * 60 * 24))
      if (!item.isDone) {
        if (0 < deltaDays && deltaDays <= 7)
          return <Text>剩余{deltaDays}天到期</Text>
        else if (deltaDays == 0)
          return <Text>今日到期!</Text>
        else if (deltaDays < 0)
          return <Text style={{ color: 'red' }}>已逾期</Text>
      }
      return null
    }

    // 删除处理函数直接调用父组件回调
    const deleteHandler = () => {
      props.onDeleteTask(item.id)
    }

    return (
      <Item
        title={item.title}
        desc={item.desc}
        checkBoxHandler={checkBoxHandler}
        calculateDeadline={calculateDeadline}
        deleteHandler={deleteHandler}
        isDone={item.isDone}
      />
    )
  }

  const onRefresh = () => {
    // 刷新逻辑可根据需求在父组件实现后通过props调用
  }

  return (
    <FlatList
      data={props.list}
      renderItem={itemRender}
      keyExtractor={item => item.id}
      onRefresh={onRefresh}
    />
  )
}

export default ItemList

内容的提问来源于stack exchange,提问作者wneo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 07:45:01