繁体   English   中英

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

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

所以我试图打乱一个句子或字符串并将单词推入一个数组以便稍后加入它们和 output 这个打乱的句子但由于某种原因,即使使用空数组,useEffect 也没有在第一次渲染上运行,但是当我更改一行时并再次运行它,它按预期运行。 我只是想知道我是否做错了什么以及如何更改它以便它在第一次渲染时运行。

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;

效果不会在渲染期间运行。

效果 function 的第一次执行将由第一次渲染触发。

下面的代码将不起作用,因为 map 需要 return 语句,所以它是未定义的,useEffect 将控制空数组,如 state 中定义的那样。 你也不应该在渲染组件中使用 let ,因为它总是会启动,使用可能是 useRef 。 此外,如果您的组件包含 js 代码,最好将其制作为帮助文件并使用它,这样可以节省并提高性能。

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

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.

此代码应该可以工作:

    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

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM