React让一个组件等待另一个组件

huangapple go评论83阅读模式
英文:

React make one component wait for another

问题

我想要一个组件的实例在另一个相同组件的实例在不同的父组件中执行完成后被调用。

我有一个名为TypeWriter的组件,它显示类型动画,每个字符之间有延迟。

const TypeWriter =  ({text,delay}) => {
  
  const [currentTxt, setCurrentText] = useState('');
  const [currentIdx, setCurrentIdx] = useState(0);

  useEffect(() => {
    let timeOut;
    
    if(text.length > currentIdx) {
      timeOut = setTimeout(() => {
        setCurrentText(currentTxt => currentTxt + text[currentIdx]);
        setCurrentIdx(currentIdx => currentIdx + 1);
      }, delay);
    }

    return () => clearTimeout(timeOut);
  }, [currentIdx]);

  return <>{currentTxt}</>;
}

问题是我希望一个TypeWriter实例在前一个完成后被调用(useEffect结束):

const SomeComponent = () => (
  <h1 className={`${styles.heroHeadText} lg:leading-normal -md:text-xl -md:mt-5`}>
    <TypeWriter text="Hello, it's me " delay={200} />
    <span className='text-[#915eff]'>
      <TypeWriter text=" name" delay={200} />
    </span>
  </h1>
)

span中的TypeWriter必须在h1中的TypeWriter完成后被实例化。

我是React的新手,请让我知道我是否可以在实例之间使用mutexLock。提前感谢(:

英文:

I want one instance of component to be called after other instance of same component completed with its execution inside a different parent component

I have a component TypeWriter that shows type animation with delay between each character being written

const TypeWriter =  ({text,delay})=&gt;{
  
  const [currentTxt, setCurrentText] = useState(&#39;&#39;);
  const [currentIdx,setCurrentIdx] = useState(0);


  useEffect(()=&gt;{
    let timeOut;
    
    if(text.length&gt;currentIdx){
      timeOut = setTimeout(()=&gt;{
        setCurrentText(currentTxt=&gt;currentTxt+text[currentIdx]);
        setCurrentIdx(currentIdx=&gt;currentIdx+1);
      },delay)
    }


    return ()=&gt;clearTimeout(timeOut);
  },[currentIdx])

  return &lt;&gt;{currentTxt}&lt;/&gt;
}

Issue is I want one TypeWriter instance to be called after previous one complete (useEffect end):

const SomeComponent = ()=&gt;return (&lt;h1 className={`${styles.heroHeadText} lg:leading-normal -md:text-xl -md:mt-5`}&gt;
   &lt;TypeWriter text=&quot;Hello, it&#39;s me &quot; delay={200}/&gt;
   &lt;span className=&#39;text-[#915eff]&#39;&gt;&lt;TypeWriter text=&quot; name&quot; delay={200}/&gt;&lt;/span&gt;
&lt;/h1&gt;)

TypeWriter inside span must be instantiated after TypeWriter inside h1 is completed

I am new to React, let me know if in anyone I can use mutexLock between instances.
Thanks in advance (:

答案1

得分: 1

以下是翻译好的部分:

最简单的解决方案我能想到的是一个回调函数,可以传递给你的TypeWriter组件。

这样,在你的SomeComponent中,你可以初始化一个状态来跟踪你的第一个TypeWriter的工作。一旦第一个打字机完成了它的工作,回调函数会更新你的第一个打字机实例的状态。

然后,一旦第一个完成,你可以有条件地渲染第二个实例。类似这样:

const TypeWriter =  ({text,delay,onComplete}) => {
  
  const [currentTxt, setCurrentText] = useState('');
  const [currentIdx,setCurrentIdx] = useState(0);


  useEffect(() => {
    let timeOut;
    
    if(text.length > currentIdx){
      timeOut = setTimeout(() => {
        setCurrentText(currentTxt => currentTxt + text[currentIdx]);
        setCurrentIdx(currentIdx => currentIdx + 1);
      }, delay)
    }
    
    if(onComplete) {
      onComplete();  
    }

    return () => clearTimeout(timeOut);
  }, [currentIdx])

  return <>{currentTxt}</>;
}

然后像这样有条件地渲染第二个实例。

const SomeComponent = () => {
  const [firstTextComplete, setFirstTextComplete] = useState(false);

  return (
       <TypeWriter text="Hello, it's me " delay={200} onComplete={() => setFirstTextComplete(true)}/>
    
       {firstTextComplete && <span className='text-[#915eff]'><TypeWriter text=" name" delay={200}/></span>}
   
  );
};
英文:

The simplest solution I can think of is a callback function that can be passed into your TypeWriter component.

This way in your SomeComponent, you can initialise a state to keep track of your first TypeWriter work. Once the first typewriter has finished its job, the callback function updates the state of your first instance of typewriter.

Then you can conditionally render your second instance once the first has finished. Something like this

const TypeWriter =  ({text,delay,onComplete})=&gt;{
  
  const [currentTxt, setCurrentText] = useState(&#39;&#39;);
  const [currentIdx,setCurrentIdx] = useState(0);


  useEffect(()=&gt;{
    let timeOut;
    
    if(text.length&gt;currentIdx){
      timeOut = setTimeout(()=&gt;{
        setCurrentText(currentTxt=&gt;currentTxt+text[currentIdx]);
        setCurrentIdx(currentIdx=&gt;currentIdx+1);
      },delay)
    }
    
    if(onComplete) {
      onComplete();  
    }

    return ()=&gt;clearTimeout(timeOut);
  },[currentIdx])

  return &lt;&gt;{currentTxt}&lt;/&gt;
}

Then conditionally render the second instance like this.

const SomeComponent = () =&gt; {
  const [firstTextComplete, setFirstTextComplete] = useState(false);

  return (
       &lt;TypeWriter text=&quot;Hello, it&#39;s me &quot; delay={200} onComplete={() =&gt; setFirstTextComplete(true)}/&gt;
    
       {firstTextComplete &amp;&amp; &lt;span className=&#39;text-[#915eff]&#39;&gt;&lt;TypeWriter text=&quot; name&quot; delay={200}/&gt;&lt;/span&gt;}
   
  );
};

huangapple
  • 本文由 发表于 2023年7月11日 01:04:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76655893.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定