简体   繁体   English

为什么我的 useEffect 没有在第一次渲染时运行?

[英]Why is my useEffect not running on first render?

So I am trying to scramble a sentence or string and push the words into an array to later join them and output this scrambled sentence but for some reason the useEffect is not running on the first render even with an empty array but when I change one line and run it again it runs as intended.所以我试图打乱一个句子或字符串并将单词推入一个数组以便稍后加入它们和 output 这个打乱的句子但由于某种原因,即使使用空数组,useEffect 也没有在第一次渲染上运行,但是当我更改一行时并再次运行它,它按预期运行。 I was just wondering if I was doing anything wrong and how I can change it so that it does run on the first render.我只是想知道我是否做错了什么以及如何更改它以便它在第一次渲染时运行。

const ScrambleSentence = ({sentence}) => {
    const [words, setWords] = useState([]);
    const [scrambledSentence, setScrambledSentence] = useState('');
    let scrambledWord = [];


    function scrambleWord(n){
        var text = n.split('');
        for(var i = text.length - 1; i > 0; i--){
            var j = Math.floor(Math.random() * (i + 1));
            var temp = text[i];
            text[i] = text[j];
            text [j] = temp;
        }
        return text.join('');
    }

    useEffect(() => {
        setWords(sentence.split(' '));


        words.map(word =>{
          if(word.length <= 2){
            scrambledWord.push(word);

          }
          else{
            scrambledWord.push(scrambleWord(word));
          }
        })
        setScrambledSentence(scrambledWord.join(' '));
      }, [])


      console.log(scrambledSentence);
    return (
        <div>
            <p id='scrambled-word'>{scrambledSentence}</p>
        </div>
    )
};

export default ScrambleSentence;

Effects don't run during a render.效果不会在渲染期间运行。

The first execution of an effect function will be triggered by the first render.效果 function 的第一次执行将由第一次渲染触发。

below code will not work as map need return statement, so it would be undefined, useEffect will console the empty array as define in the state.下面的代码将不起作用,因为 map 需要 return 语句,所以它是未定义的,useEffect 将控制空数组,如 state 中定义的那样。 also you should not use let in render components as it will always initate, use may be useRef for that.你也不应该在渲染组件中使用 let ,因为它总是会启动,使用可能是 useRef 。 also if your component consist js code, better to make it helper file and use it, would save and boost the performance.此外,如果您的组件包含 js 代码,最好将其制作为帮助文件并使用它,这样可以节省并提高性能。

 words.map(word =>{
              if(word.length <= 2){
                scrambledWord.push(word);
    
              }
              else{
                scrambledWord.push(scrambleWord(word));
              }
            })

useEffect is called after the first render however the issue in your code is that the words state isn't updated when you think it is. useEffect 在第一次渲染后被调用,但是您的代码中的问题是 state 字样在您认为更新时没有更新。

useEffect(() => {
        setWords(sentence.split(' ')); 
// Here you set the words state that will trigger a new render. However the words variable is empty won't be changed until the next render


        words.map(word =>{ //Here you call map on an empty array.
          if(word.length <= 2){
            scrambledWord.push(word);

          }
          else{
            scrambledWord.push(scrambleWord(word));
          }
        })

        setScrambledSentence(scrambledWord.join(' ')); 
        //Here you set the state on an empty string
      }, [])
// the useEffect doesn't run a second time because it has no dependencies.

This code should work:此代码应该可以工作:

    const ScrambleSentence = ({sentence}) => {
    const [scrambledSentence, setScrambledSentence] = useState('');
    let scrambledWord = [];


    function scrambleWord(n){
        var text = n.split('');
        for(var i = text.length - 1; i > 0; i--){
            var j = Math.floor(Math.random() * (i + 1));
            var temp = text[i];
            text[i] = text[j];
            text [j] = temp;
        }
        return text.join('');
    }

    useEffect(() => {

        const words = sentence.split(' ')
        words.forEach(word =>{
          if(word.length <= 2){
            scrambledWord.push(word);
          }else{
            scrambledWord.push(scrambleWord(word));
          }
        })

        setScrambledSentence(scrambledWord.join(' '));
      }, [])


      console.log(scrambledSentence);
    return (
        <div>
            <p id='scrambled-word'>{scrambledSentence}</p>
        </div>
    )
};

export default ScrambleSentence;

https://reactjs.org/docs/hooks-state.html https://reactjs.org/docs/hooks-effect.html https://reactjs.org/docs/hooks-state.html https://reactjs.org/docs/hooks-effect.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 useEffect 在第一次渲染时运行? - why is useEffect running on first render? 我想知道为什么当我使用 useEffect 在第一次渲染时填充它时,我的 useEffect 数据在第一次渲染时是空的 - I am wondering why my useEffect data is empty on first render when I populate it on first render using useEffect 为什么 useEffect 中的代码在第一次渲染时会运行两次? - Why does code inside useEffect run twice for the first render? 为什么这个 UseEffect 会在每次渲染时继续运行,即使在依赖项被填充的情况下? - Why Is This UseEffect Keep on Running on Every Render Even When Dependency Is Filled? 为什么 useEffect 在启动时不渲染我的图表? - Why doesn't useEffect render my graph on startup? 避免 useEffect 在第一次加载时渲染? - avoid useEffect to render at first load? 为什么 useEffect 运行一次? - Why is useEffect running once? 为什么我的 useEffect() 没有在更改或页面刷新时运行 - React Js? - Why is my useEffect() not running on change or page refresh - React Js? React useEffect Hook 不会在具有 [] 依赖项的第一次渲染时触发 - React useEffect Hook not Triggering on First Render with [] Dependencies React:如何在第一次渲染时跳过 useEffect - React: How to skip useEffect on first render
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM