7

我试图在我的反应钩子中使用 useEffect() 来更新我的道具改变时的状态。但是有一个延迟,并且只有在我再次单击我的钩子中的一个元素后才会触发 useEffect 。我对使用钩子相当陌生,任何帮助将不胜感激。谢谢

function ImageOrderSelect (props) {
  const [clicked, setClicked] = useState(false)
  const [options, setOptions] = useState(props.options)
  const [current, setCurrent] = useState(props.current)

  useEffect(() => {
      setCurrent(props.current)
    }, [props.current])


  if(!clicked){
    return (
        <div className="image-order-select-icon" onClick={() => setClicked(!clicked)}>
            <FontAwesomeIcon size="lg" icon={faCircle} />
            <p>{current}</p>
        </div>
    )
  } else if(clicked){
      return (
          <div className="image-order-select">
              {optionsList}
          </div>
      )
  }


}
4

3 回答 3

9
    useEffect(() => {

      setTimeout(()=>{
       setCurrent(props.current)
      }, 1000)
  
    }, [props.current])

您只需要在显示当前...之前添加超时/延迟

或最佳方法添加回调函数

useEffect(() => {

 
   setCurrent(() => props.current)
  

}, [props.current])
于 2020-01-07T04:18:49.867 回答
1

我不完全确定你想要什么效果,但这里有一些你的清理代码。也许这会进一步帮助你。

function ImageOrderSelect ({ current, options ) { // deconstruct here to save code
  const [clicked, setClicked] = useState(false);
  // you dont have to keep additional state since props is a state.
  useEffect(() => {
    setTimeout(() => {
      // do something here 1 sec after current has changed
    }, 1000);
  }, [current]);

  useEffect(() => {
    setTimeout(() => {
       // do something 1 sec after clicked has changed
    }, 1000);
  }, [clicked]);

  if(!clicked){
    return (
        <div className="image-order-select-icon" onClick={() => setClicked(!clicked)}>
            <FontAwesomeIcon size="lg" icon={faCircle} />
            <p>{current}</p>
        </div>
    )
  } else if(clicked){
      return (
          <div className="image-order-select">
              {optionsList}
          </div>
      )
  }
}

如果您希望在最后一次单击图像后 1 秒触发效果,则必须在每次单击时重置超时,直到超时。这是对用户交互的任何延迟影响的常见做法:

let timeout;

useEffect(() => {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
     // do something 1 sec after a click is done
     // but dont do anything if another click happened before 1sec of the previous 
     // click has expired
  }, 1000);
}, [clicked]);

如果您可以提供更详细的代码示例并更深入地解释您想要的 UI 效果,我可以明确地帮助您。

于 2020-07-03T06:18:04.503 回答
0
  let optionsList = options.map((option, index) => {
  return (
  <div key={index} onClick={() => {

      props.handleImageSort(option, props.index)
      setTimeout(() => {
          setClicked(!clicked)
      }, .500)
  }}>
    <p>{option}</p>
  </div>
  )

})

问题是我试图同时调用 setClicked ,由于某种原因阻止它调用。setTimeout 使它工作虽然不理想。如果有人有更好的解决方案,将会有兴趣听到它。

于 2019-09-04T13:01:11.530 回答