求助一下关于 react 更新 list 的一个疑问。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
hi20151215x
V2EX    程序员

求助一下关于 react 更新 list 的一个疑问。

  •  
  •   hi20151215x 2022-07-26 15:43:48 +08:00 2435 次点击
    这是一个创建于 1241 天前的主题,其中的信息可能已经有所发展或是发生改变。
     TodoList.map((item,index)=>{ return <Todo key=index total=TodoList.length> }) 

    现状:子组件 Todo 获取到的 total 值 分别是 1,2,3.....

    想要获得的结果:每当 List 更新时,所有子组件的 total 也都更新(所有子组建的 total 项一致,并且和 TodoList.length 相同)。

    在 google 用英文搜索好些结果,但因为英文描述问题,总是找不到确切的答案。 :) thanks in advance

    第 1 条附言    2022-07-26 17:08:47 +08:00
     const [todoList,setTodoList] = useState([]) const clickHandler=()=>{ setTodoList([...todoList,'new todo!']) } return ( <View> <Button OnClick={()=>clickHandler()}>click to add new Todo.</Button> {todoList.map((item,index)=>{ return <View><Todo cOntent={item} size={todoList.length}></Todo></View> })} </View> ) 
    内容:new todo TodoList尺寸:1 内容:new todo TodoList尺寸:2 内容:new todo TodoList尺寸:3 内容:new todo TodoList尺寸:4 内容:new todo TodoList尺寸:5 

    而期望得到的结果是

    内容:new todo TodoList尺寸:5 内容:new todo TodoList尺寸:5 内容:new todo TodoList尺寸:5 内容:new todo TodoList尺寸:5 内容:new todo TodoList尺寸:5 
    第 2 条附言    2022-07-26 17:45:14 +08:00

    todo 组件的代码

    function Todo(props) { const [content, setContent] = useState() const [size, setSize] = useState() useEffect(()=>{ setContent(props.content) setSize(props.size) },[content,size]) return ( <View>内容:{content} TodoList尺寸:{size}</View> ) } 
    27 条回复    2022-07-27 10:19:45 +08:00
    happyeveryday
        1
    happyeveryday  
       2022-07-26 15:59:03 +08:00
    不就是 react 最基础的如何更新 state 然后 rerender 嘛...
    codehz
        2
    codehz  
       2022-07-26 16:05:18 +08:00
    (你不会直接原地 push 到数组的吧
    hi20151215x
        3
    hi20151215x  
    OP
       2022-07-26 16:05:59 +08:00
    @happyeveryday 每次新添加 todo 到 list 都能够 re-render 。 但就是结果不是想要的
    hi20151215x
        4
    hi20151215x  
    OP
       2022-07-26 16:06:29 +08:00
    @codehz 嗯。。是的。难道???问题在这里?
    Leviathann
        5
    Leviathan  
       2022-07-26 16:09:11 +08:00
    key 不要设为 index
    ryncv
        6
    ryncv  
       2022-07-26 16:16:37 +08:00
    setState({TodoList: [...TodoList]})
    wenzichel
        7
    wenzichel  
       2022-07-26 16:34:17 +08:00
    无论是类组件还是函数组件,不要直接操作 TodoList 。

    在类组件中,是使用 this.setState()来操作的;在函数组件里,是用 const [TodoList, setTodoList] = useState()这个 hook 中的第 2 个参数 setTodoList()来操作的。
    yaphets666
        8
    yaphets666  
       2022-07-26 16:53:22 +08:00
    vue 里直接 push 就行,react 不是这个套路
    pengtdyd
        9
    pengtdyd  
       2022-07-26 17:07:03 +08:00
    key 不要设为 index ,key 会被动态赋值,导致不可预知的 bug
    Alander
        10
    Alander  
       2022-07-26 17:16:39 +08:00
    乍一看 append 的代码我竟看不出来这段代码是否真的会如作者所说的 1 ,2 ,3 ,4 ,5
    应该全是 5 才对
    fengfuliu
        11
    fengfuliu  
       2022-07-26 17:17:50 +08:00
    setTodoList([...todoList,'new todo!'])改成 setTodoList(prev=>([...prev,'new todo!']))
    hi20151215x
        12
    hi20151215x  
    OP
       2022-07-26 17:18:34 +08:00
    @Alander 如果在当前组件 全是 5 ,但是传递到子组件后 就不是了。
    zhangdroid
        13
    zhangdroid  
       2022-07-26 17:23:37 +08:00
    append 的代码应该是可以得到预期的结果的, 有问题的话有可能是 Todo 这个组件有问题, 比如用了 memo/shouldComponentUpdate
    Alander
        14
    Alander  
       2022-07-26 17:30:51 +08:00
    @hi20151215x 如 13 楼所说,希望能贴出来 Todo 组件的代码才能更好的知道为什么。至于纠正你如何去 setState 的可以忽略
    Alander
        15
    Alander  
       2022-07-26 17:32:04 +08:00
    @hi20151215x 确实是不应该直接 push ,但是你 append 后的代码更新方式已经是正确更新方式了,所以直接看一下 Todo 组件的代码应该可以发现端倪
    churchill
        16
    churchill  
       2022-07-26 17:36:26 +08:00
    你是不是在啊
    hi20151215x
        17
    hi20151215x  
    OP
       2022-07-26 17:45:37 +08:00
    @churchill 都快抓耳挠腮了。
    hi20151215x
        18
    hi20151215x  
    OP
       2022-07-26 17:46:16 +08:00
    @Alander 代码已更新 希望得到您回复:)
    codehz
        19
    codehz  
       2022-07-26 17:47:39 +08:00
    咦 ,
    const [content, setContent] = useState()
    const [size, setSize] = useState()
    useEffect(()=>{
    setContent(props.content)
    setSize(props.size)
    },[content,size])
    这是在干啥
    用内部的 state 作为 effect 的 deps 参数吗,那肯定不会更新啊(另外推荐开 eslint
    直接在 jsx 里用 props 上的属性就可以了
    westoy
        20
    westoy  
       2022-07-26 17:55:07 +08:00
    Todo 加个 key={`item-${index}-${todoList.length}`}
    freeman12
        21
    freeman12  
       2022-07-26 17:56:11 +08:00
    子组件直接 props.size 用就好了,干嘛存到自己的 state
    freeman12
        22
    freeman12  
       2022-07-26 17:56:47 +08:00
    这样<View>内容:{content} TodoList 尺寸:{props.size}</View>
    silk
        23
    silk  
       2022-07-26 17:57:41 +08:00
    ,[content,size] 去掉观察目标 有变化就更新 或者按照#19
    yunyuyuan
        24
    yunyuyuan  
       2022-07-26 18:19:25 +08:00
    你 todo 组件 useEffect 的依赖填错了,应该是 props.content 和 props.size ,而且这样写是脱裤子放屁。。。
    hi20151215x
        25
    hi20151215x  
    OP
       2022-07-26 18:22:25 +08:00
    @codehz
    @westoy
    @freeman12
    @silk
    谢谢大家 问题已经解决啦。使用了 freeman12 的主意 :) 感谢
    shakukansp
        26
    shakukansp  
       2022-07-26 18:29:47 +08:00
    props 变动可以触发组件重渲染,所以
    function Todo(props) {
    return (
    <View>内容:{props.content} TodoList 尺寸:{props.size}</View>
    )
    }
    Envov
        27
    Envov  
       2022-07-27 10:19:45 +08:00
    useEffect(() => {
    setContent(props.content);
    setSize(props.size);
    }, [content, size]);
    这个依赖项写错了,导致结果是 useEffect 内的函数不会执行
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2820 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 14:22 PVG 22:22 LAX 06:22 JFK 09:22
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86