簡體   English   中英

React hooks:如何使用 useState() 更新嵌套對象的狀態?

[英]React hooks: How do I update state on a nested object with useState()?

我有一個組件,它接收一個看起來像這樣的道具:

const styles = {
    font: {
        size: {
            value: '22',
            unit: 'px'
        },
        weight: 'bold',
        color: '#663300',
        family: 'arial',
        align: 'center'
    }
};

我正在嘗試更新align屬性,但是當我嘗試更新對象時,我最終只用align屬性替換了整個對象。

這就是我更新它的方式:

const { ...styling } = styles;
const [style, setStyle] = useState(styling);

return (
        <RadioButtonGroup
            onChange={(event) => {
                setStyle({ ...style, font: { align: event.target.value } });
                console.log(style);
            }}
        />);

當我使用 console.log style我只會得到{"font":{"align":"left"}}回來。 我希望看到整個對象具有align的更新值。 我是解構的新手,所以我在這里做錯了什么?

您還需要使用擴展語法來復制字體對象屬性。 此外,在嘗試根據以前更新當前狀態時,請使用回調模式

<RadioButtonGroup
  onChange={(event) => { 
    setStyle(prevStyle => ({
        ...prevStyle,
        font: { ...prevStyle.font, align: event.target.value }
    }));
    console.log(style);
  }}
/>

這是你的錯誤

setStyle({
    ...style,
    font: { align: event.target.value } // This code replace the font object
});

要保留所有font對象值,您可以這樣做

const onChange = (event) => {
    const s = {...style};
    s.font.align = event.target.value;
    setStyle(s);
}

或者

const onChange = (event) => {
    setStyle({ 
        ...style,
        font: {
            ...style.font, // Spread the font object to preserve all values
            align: event.target.value
        }
    });
}

如果嵌套對象中有多個值,請嘗試以下方法:

setPost({
  ...post,
  postDetails: {
    ...post.postDetails,
    [event.target.name]: event.target.value,
  },
});

您可以通過這種方式更新樣式

onChange={(event) => {
    const s = {...styles};
    s.font.align = event.target.value;
    setStyle(s);
    console.log(style);
}}

您的默認 useState 代碼無效。 對於默認的 useState,您應該像下面這樣寫:

  const { ...styling } = styles;
  const [style, setStyle] = useState({ styling }); // styling should be use in {}

return (
        <RadioButtonGroup
          onChange={event => {
            setStyle({
              ...styling,
              font: { ...styling.font, align: event.target.value }
            });
            console.log(style);
          }}
        />);

演示:用console.log檢查這個演示。

編輯 awesome-diffie-pflqz

第一: const { ...styling } = styles; 等同於: const styling = styles;

但是你可以完全跳過它,只需使用[...] = useState(styles)

setStyle()接受一個接收當前狀態的函數,在你的案例風格中。 因此,您可以使用擴展運算符...來創建新對象並向其添加值。

setStyle(style => ({ ...style, font: { ...style.font, align: event.target.value } ) ) );

上面的代碼使用了箭頭函數,這也可以寫成一個普通的函數,但可能更容易理解:

setStyle( function (style) {
    return  {
        ...style,
        font: {
            ...style.font,
            align: 'center'
        }
    }
});

setStyle console.log顯示當前樣式,因為在下次渲染時會看到更改的樣式。 所以我在返回之前移動了console.log

const [style, setStyle] = useState(styles);

console.log(style);

return (
        <RadioButtonGroup
            onChange={(event) => {
                setStyle(style => ({ ...style, font: { ...style.font, align: event.target.value } ) ) );
            }}
        />);

這里有一些鏈接可以幫助您理解所有這些:

暫無
暫無

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

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