react的hook逻辑?

tsconfig.json

    const [show, setShow] = useState<boolean>(false)
    const [text, setText] = useState<string>('')
    const active = (p: typeof div) =>{
        setShow(view=>{
            $.Msg('log1 ',view)
            if(view){
                SendCustomEventToServer('aaa',{item:p.title})
                // setText(lab=>{
                //     $.Msg('log2 ', lab)
                //     return ''
                // })
            }
            return false
        })
    }

函数式组件中的一段,点击触发active:当view为真时,下一行会像服务端触发事件。而诡异的事情发生在嵌套运行hook上:
如上文执行时,log1 打印后,事件正常触发。
取消注释并执行时,会打印

log1 true
log2 text
log1 true
log2 

但是事件并没有触发。
log2是写在触发事件下面的,为什么log2都打印了还不触发,反而还打印了两遍?

但在 useeffect的回调中却是正常使用:

useEffect(()=>{
   let event:{title:string} = .....
        setShow(view=>{
            setText(lab => {
                if (view) {
                    $.Msg('处理旧事件', lab)
                    SendCustomEventToServer('aaa',{ item: lab }) 
                }
                $.Msg('更新事件名', event.title)
                return event.title
            })
            return false
        })
},[...其他变量])
阅读 2k
1 个回答

这又是什么神仙写法~

  1. 状态更新函数应该是个纯函数,并且什么时候执行状态更新函数是React内部的事情,不同的Reactjs版本可能行为还不一致(Reactjs也在不断优化)。
  2. 副作用应该在useEffect里执行。
    建议调整下写法,例如:

    const [show, setShow] = useState<boolean>(false);
    const [text, setText] = useState<string>('');
    const titleRef = useRef();
    
    const active = (p: typeof div) =>{
     setShow(false);
     titleRef.current = p.title;
    }
    
    useEffect(() => {
     $.Msg('log1 ',show);
     if(show){
         SendCustomEventToServer('aaa', {item: titleRef.current});
         setText("");
     }
    }, [show])
    
    useEffect(() => {
      $.Msg('log2 ', text)
    }, [text])
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题