[英]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.