簡體   English   中英

React,組件在數組狀態更改后不重新渲染(與其他不同)

[英]React, component not re-rendering after change in an array state (not the same as others)

我正在嘗試創建一個從服務器獲取圖片的頁面,一旦下載了所有圖片,就會顯示它們,但由於某種原因,當我更新狀態時頁面不會重新呈現。

我已經看到了這個問題的其他答案,您必須將一個新數組傳遞給setImages函數,而不是先前數組的更新版本,我正在這樣做,但它仍然不起作用。

(有趣的是,如果我將 console.log 放在useEffect中,它會在重新渲染數組時記錄文本,但頁面不會顯示更新的信息)

如果有人可以提供幫助將不勝感激!

這是我的代碼。

 export function Profile() {
    const user = JSON.parse(window.localStorage.getItem("user"));
    const [imgs, setImages] = useState([]);
    const [num, setNum] = useState(0);
    const [finish, setFinish] = useState(false);

    const getImages = async () => {
        if (finish) return;
        let imgarr = [];
        let temp = num;
        let filename = "";
        let local = false;
        while(temp < num+30) {
            fetch("/get-my-images?id=" + user.id + "&logged=" + user.loggonToken + "&num=" + temp)
            .then(response => {
                if(response.status !== 200) {
                    setFinish(true);
                    temp = num+30;
                    local = true;
                }
                filename = response.headers.get("File-Name");
                return response.blob()
            })
            .then(function(imageBlob) {
                if(local) return;
                const imageObjectURL = URL.createObjectURL(imageBlob);
                imgarr[temp - num] = <img name={filename} alt="shot" className="img" src={imageObjectURL}  key={temp} />
                temp++;
            });
        }
        setNum(temp)
        setImages(prev => [...prev, ...imgarr]);
    }

    async function handleClick() {
        await getImages();
    }

    return (
        <div>
            <div className="img-container">
                {imgs.map(i => {
                    return (
                        i.props.name && <div className="img-card">
                            <div className="img-tag-container" onClick={(e) => handleView(i.props.name)}>{i}</div>
                            
                            <div className="img-info">
                                <h3 className="title" onClick={() => handleView(i.props.name)}>{i.props.name.substr(i.props.name.lastIndexOf("\\")+1)}<span>{i.props.isFlagged ? "Flagged" : ""}</span></h3>
                            </div>
                        </div>
                    )
                })}
            </div>
            <div className="btn-container"><button className="load-btn" disabled={finish} onClick={handleClick}>{imgs.length === 0 ? "Load Images" : "Load More"}</button></div>
        </div>
    )
}

我認為您創建新數組的方法是正確的。 您正在將更新程序回調傳遞給 useState() 更新程序函數,該函數返回先前圖像和新圖像的串聯,這應該返回一個新數組。

使用基於集合的狀態變量時,我強烈建議設置渲染子項的key屬性。 您是否嘗試為<div className="img-card">分配唯一鍵? 看來i.props.name足夠獨特,可以用作鍵。

鍵是 React 如何將集合中的單個項目與它們對應的渲染 DOM 元素相關聯。 如果您修改該集合,它們尤其重要。 每當呈現集合出現問題時,我總是確保鍵是有效且唯一的。 即使添加密鑰不能解決您的問題,出於性能原因,我仍然強烈建議您保留它。

它與javascript的Array特性有關。 控制台日志的原因與控制台日志打印時刻有關。 因此,它應該稍后顯示為您更新。

有幾種方法。

const getImages = async () => {
      ... ...
        setNum(temp)
        const newImage = [...prev, ...imgarr];
        setImages(prev => newImage);
    }
const getImages = async () => {
      ... ...
        setNum(temp)
        setImages(prev => JOSN.parse(JSON.object([...prev, ...imgarr]);
    }
const getImages = async () => {
      ... ...
        setNum(temp)
        setImages(prev => [...prev, ...imgarr].slice(0));
    }

也許它可以工作。 希望對您有所幫助。

好的,對我來說問題是服務器沒有發送正確的filename標頭,因此它始終為空,因此條件i.props.name永遠不會為真...大聲笑抱歉造成混亂。

所以這個故事的寓意是,在開始尋找其他解決方案之前,請始終確保代碼中沒有其他東西導致不良行為......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM