[英]React useState not updating because of useRef
我的反應代碼遇到了一個非常奇怪的問題:useState 沒有更新視圖,在嘗試了所有內容之后,問題仍然存在。 我做了一個簡單的代碼來解釋這個問題:
function(){ const [enterJob, setEnterJob] = useState(false); const [jobSelection, setJobSelection] = useState(Array(someList.length).fill(false)); const jobRef = useRef(); const handleJobClick = i => { const n = parseInt(i.target.id.charAt(0)); // the list is small enough to allow this let c = jobSelection; c[n] = !c[n]; setJobSelection(c); }; const handleMouse = (e) =>{ if (!jobRef.current.contains(e.target)){ setEnterJob(false); }; }; useEffect(() => { window.addEventListener("mousedown", handleMouse); return () => window.removeEventListener("mousedown", handleMouse); }); return( <div ref={jobRef}> <input onFocus={()=> setEnterJob(true)} /> <div style={{display: `${enterJob ? 'flex' : 'none'}`}} > <ul> { someList.map((item,index)=> <li id={`${index}`} onClick={handleJobClick}> {jobSelection[index] ? item : "you clicked on the button"} </li> )} </ul> </div> </div> ) }
一些解釋:我正在使用 UseEffect 和 useRef 創建一個下拉菜單,當您在容器外單擊時該菜單會消失。 現在,當我想單擊此下拉菜單的值時,它不會更新 DOM,而我正在使用 useState 更新負責更改的字符串的值。
提前謝謝你,查貝爾
問題是您正在改變jobSelection
而不是創建新對象。 如果對象具有與以前相同的引用,react 將跳過重新渲染:
const handleJobClick = i => {
const n = parseInt(i.target.id.charAt(0)); // the list is small enough to allow this
let c = [...jobSelection]; // Create a new array
c[n] = !c[n];
setJobSelection(c);
};
如果我理解您的問題,那么我相信這是因為您正在直接改變您的狀態。
const handleJobClick = i => {
const n = parseInt(i.target.id.charAt(0)); // the list is small enough to allow this
let c = jobSelection;
c[n] = !c[n]; // <-- mutation!
setJobSelection(c);
};
您還缺少映射列表項上的反應鍵。
由於下一個狀態取決於前一個狀態,因此您應該先使用功能狀態更新來復制您的狀態,然后再更新它。
我建議:
handleJobClick
轉換為直接使用索引,一個handleJobClick
函數可以干凈地處理這個代碼
const handleJobClick = index => () => {
setJobSelection(jobSelection => jobSelection.map(
(selection, i) => index === i ? !selection : selection // <-- toggle selection at matched index
);
};
...
<ul>
{someList.map((item, index)=> (
<li
key={index} // <-- index as react key, ok since not adding/removing/sorting jobs
onClick={handleJobClick(index)} // <-- pass index to handler
>
{jobSelection[index] ? item : "you clicked on the button"}
</li>
))}
</ul>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.