JavaScript >> Javascript 文檔 >  >> React

當使用 key 屬性時,react useState 中的狀態會更新,但需要 useEffect 或類似方法才能更新

我有以下組件:

import React, { useState } from "react";
import { FormControl, TextField } from "@material-ui/core";

interface IProps {
    text?: string;
    id: number;
    onValueChange: (text: string, id: number) => void;
    placeholder: string;
}

export const QuestionTextRow: React.FC<IProps> = (props) => {
    const [item, onItemChange] = useState(props.text);

    const onChange = (e: React.FormEvent<HTMLInputElement>) => {
        const newValue = e.currentTarget.value;

        onItemChange(newValue);
        props.onValueChange(newValue, props.id);
    };

    return (
        <>
            <FormControl fullWidth>
                <div>{props.text}</div>
                <TextField
                    aria-label="question-text-row"
                    onDragStart={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                    }}
                    value={item}
                    onChange={(ev: React.ChangeEvent<HTMLInputElement>): void => {
                        onChange(ev);
                    }}
                />
            </FormControl>
        </>
    );
};

它通過以下組件呈現:

const renderQuestionOptions = (id: number): JSX.Element => {
    const item = props.bases.find((x) => x.sortableId === id);

    if (!item) return <> </>;

    return (
        <div className={classes.questionPremiseRow}>
            <div className={classes.rowOutline}>
                <QuestionOptionsSortableRow item={item} isDisabled={false} onClickRow={onClickBasisRow}>
                    <QuestionTextRow
                        text={item.text ? item.text.text : ""}
                        id={item.sortableId}
                        onValueChange={basisValueChanged}
                        placeholder={intl.formatMessage({ id: "question.create.basis.row.placeholder" })}
                    ></QuestionTextRow>
                </QuestionOptionsSortableRow>
            </div>
        </div>
    );
};

它呈現以下列表:

如您所見 0618 2535 均等地呈現。如果 42 已更新它不會反映在 50 不過。

https://stackoverflow.com/a/53846698/3850405

我可以通過 65 解決它 讓它發揮作用:

useEffect(() => {
    onItemChange(props.text);
}, [props.text]);

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

https://stackoverflow.com/a/54866051/3850405

但是,如果我添加 7982 它可以在不使用 95 的情況下工作 .怎麼會?

我知道應該使用靜態唯一鍵,但如果 101 會不會是相同的結果 用過嗎?

https://www.npmjs.com/package/react-key-index

傳遞給 useState 的參數是初始狀態,很像在類組件的構造函數中設置狀態,並且不用於在重新渲染時更新狀態

https://stackoverflow.com/a/43892905/3850405

回答

但是,如果我添加 key={114 } toQuestionTextRow 它將在不使用 useEffect 的情況下工作。怎麼會?

那是因為和解。在反應中,當你在一個渲染時說:

<SomeComponent key={1}/>

如果在下一次渲染中,您使用 不同的鍵 渲染相同的組件(在同一位置) ,說:

<SomeComponent key={2}/>

React 將銷毀與先前組件相關的實例並為此創建一個新實例,因此 122 該組件內部將使用提供的 132 進行初始化 再次屬性(就像你第一次創建組件時一樣)。

如果上一次和下一次渲染中某些組件的鍵相同,而您只是更改了其他一些道具,在這種情況下,該組件會被重新渲染(沒有實例被破壞),這就是您沒有看到 147 屬性反映在狀態中。

有時,將 props 複製到您在 155 中的狀態可能會很棘手 解決方案,我建議你閱讀這篇文章,它是關於課程但同樣適用的想法。


Tutorial JavaScript 教程
  1. Typecsript 和 NextJS 如何檢查“文檔”是否存在

  2. 如何在您的 Web 應用程序中使用 jQuery Splitter UI 組件 - 第 1 部分

  3. 在反應中顯示評級星星不顯示任何星星

  4. 沒有 http、https、ftp 的 url 的正則表達式

  5. 錯誤:請求失敗,狀態碼 400 – React – API Key

  6. 使用 HTML5 進行相機和視頻控制

  7. 內容安全策略:CSP 是否應該包含外部腳本的哈希值?

  1. 如何在 Chrome 中為從 MediaRecorder 錄製的音頻添加預定義長度?

  2. 使用 ngFor 在 Angular 14 中構建動態 HTML 表

  3. 防止孤立詞但排除標籤

  4. 將數組轉換為對象

  5. Internet Explorer 的圖像 onLoad 事件 + JavaScript 問題

  6. 如何使用 JavaScript 中的格式規範將字符串轉換為日期時間?

  7. 在圖表中顯示數據庫中的項目

  1. 在這個免費的 28 部分 Scrimba 課程中學習 ES6

  2. 如何使用 Dialogflow 為 Google Assistant 操作實現本地實現

  3. 創建一個簡單的 Web 擴展

  4. 如何使用 D3.js 構建歷史價格圖表