web-dev-qa-db-ja.com

Reactフック:ネストされたオブジェクトの状態を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の更新された値でオブジェクト全体が表示されることを期待していました。私は解体に慣れていないので、ここで何が間違っていますか?

5
codemon

これはあなたの間違いです

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
        }
    });
}
0
tolotra

最初:_const { ...styling } = styles;_は次と同じです:_const styling = styles;_

ただし、それを完全にスキップすることもできます。[...] = useState(styles)を使用するだけです。

setStyle()は、現在の状態を受け取る関数をケーススタイルで受け入れます。したがって、スプレッド演算子_..._を使用して新しいオブジェクトを作成し、それに値を追加できます。

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

上記のコードはArrow関数を使用していますが、これも通常の関数として記述できますが、おそらく理解しやすいでしょう。

_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 } ) ) );
            }}
        />);
_

以下は、そのすべてを理解するのに役立つリンクです。

0
user3414333

デフォルトの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でこのデモを確認してください。

Edit awesome-diffie-pflqz

0