反応フックを使用するときにプロパティの変更を親コンポーネントに通知するにはどうすればよいですか?

ジムオット

親コンポーネントと子コンポーネントがあるとしましょう。親コンポーネントは、いくつかの子コンポーネントで構成されています。親コンポーネントは、非常に複雑で深いデータオブジェクトを保持および管理します。各子コンポーネントは、メインデータオブジェクトのさまざまな子オブジェクトとプロパティを管理するためのUIを提供します。子コンポーネントがデータオブジェクト階層のプロパティ値を変更するたびに、その変更はメインデータオブジェクトにバブルアップする必要があります。

これが、コールバックオブジェクトを渡すことによって子コンポーネントクラスでそれを行う方法です...

<div>
  <button onClick={e => this.setState({propA: e.target.value}, () => props.onChangePropA(this.state.propA)}>Prop A</button>
  <button onClick={e => this.setState({propB: e.target.value}, () => props.onChangePropB(this.state.propB)}>Prop B</button>
</div>

フックを使用してそれを行う必要があると私が考える方法とは対照的です。私が見ている主な問題は、状態の変更が完了した後のコールバックオプションがないことです。したがって、useEffectでそれを検出し、どのプロパティが変更されたかを把握する必要があります...

let prevPropA = props.propA;
let prevPropB = props.propB;

const [propA, setPropA] = useState(props.propA);
const [propB, setPropB] = useState(props.propB);

useEffect(() => { 
  if (prevPropA != propA) props.onChangePropA(propA); 
  if (prevPropB != propB) props.onChangePropB(propB); 
});

<div>
  <button onClick={e => {prevPropA = propA; setPropA(e.target.value)}}>Prop A</button>
  <button onClick={e => {prevPropB = propB; setPropB(e.target.value)}}>Prop B</button>
</div>

この方法は非常に面倒で面倒になります。これを達成するためのより堅牢で適切な方法はありますか?

ありがとう

================================================== ===========

以下は、Shubhamの回答とRyanのフィードバックに基づいて更新されたサンプルコードです。Shubhamは質問に答えましたが、Ryanは、正しい答えに対して正しい情報を提供できるように、より徹底的な例を示すことを提案しています。これは私の実際の状況をより厳密に追跡するサンプルコードです...まだ単純化された例ですが。親コンポーネントは、ユーザーからのコメントを管理します。彼らが新しいコメントを作成し、日付または日付範囲を選択できると想像してみてください。また、既存のコメントを更新することもできます。日付と日付範囲セレクターを独自のコンポーネントに配置しました。したがって、親コメントマネージャコンポーネントには、コメントを作成/ロードし、関連する日付を日付セレクタコンポーネントに渡す機能が必要です。その後、ユーザーは日付を変更できます。これらの値は、後でサーバーに送信して保存するために、親コメントマネージャーに伝播して戻す必要があります。ご覧のとおり、プロパティ値(日付など)の双方向のフローがあり、どちらの端からでもいつでも変更できます。注:この新しい例は、Shubhamが私の元の質問に基づいて提案したのと同様の方法を使用して更新されています。

================================================== ===========

const DateTimeRangeSelector = (props) =>
{
    const [contextDateStart, setContextDateStart] = useState(props.contextDateStart);
    const [contextDateEnd, setContextDateEnd] = useState(props.contextDateEnd);
    const [contextDateOnly, setContextDateOnly] = useState(props.contextDateOnly);
    const [contextDateHasRange, setContextDateHasRange] = useState(props.contextDateHasRange);

    useEffect(() => { setContextDateStart(props.contextDateStart);  }, [ props.contextDateStart  ]);
    useEffect(() => { if (contextDateStart !== undefined) props.onChangeContextDateStart(contextDateStart);  }, [ contextDateStart  ]);

    useEffect(() => { setContextDateEnd(props.contextDateEnd);  }, [ props.contextDateEnd  ]);
    useEffect(() => { if (contextDateEnd !== undefined) props.onChangeContextDateEnd(contextDateEnd); }, [ contextDateEnd  ]);

    useEffect(() => { setContextDateOnly(props.contextDateOnly);  }, [ props.contextDateOnly  ]);
    useEffect(() => { if (contextDateOnly !== undefined) props.onChangeContextDateOnly(contextDateOnly); }, [ contextDateOnly  ]);

    useEffect(() => { setContextDateHasRange(props.contextDateHasRange); }, [ props.contextDateHasRange  ]);
    useEffect(() => { if (contextDateHasRange !== undefined) props.onChangeContextDateHasRange(contextDateHasRange);  }, [ contextDateHasRange  ]);


    return <div>
    <ToggleButtonGroup 
        exclusive={false}
        value={(contextDateHasRange === true) ? ['range'] : []}
        selected={true}
        onChange={(event, value) => setContextDateHasRange(value.some(item => item === 'range'))}
        >
        <ToggleButton value='range' title='Specify a date range'  > 
            <FontAwesomeIcon icon='arrows-alt-h' size='lg' />
        </ToggleButton>
    </ToggleButtonGroup>

    {
        (contextDateHasRange === true)
        ?
        <DateTimeRangePicker 
            range={[contextDateStart, contextDateEnd]} 
            onChangeRange={val => { setContextDateStart(val[0]); setContextDateEnd(val[1]);  }}
            onChangeShowTime={ val => setContextDateOnly(! val) }
            />
        :
        <DateTimePicker
            selectedDate={contextDateStart} 
            onChange={val => setContextDateStart(val)}
            showTime={! contextDateOnly}
        />

    }
</div>
}


const CommentEntry = (props) =>
{
    const [activeComment, setActiveComment] = useState(null);

    const createComment = () =>
    {
        return {uid: uuidv4(), content: '', contextDateHasRange: false,  contextDateOnly: false, contextDateStart: null, contextDateEnd: null};
    }

    const editComment = () =>
    {
        return loadCommentFromSomewhere();
    }

    const newComment = () =>
    {
        setActiveComment(createComment());
    }

    const clearComment = () =>
    {
        setActiveComment(null);
    }

    return (
    <div>

        <Button onClick={() => newComment()} variant="contained">
            New Comment
        </Button>
        <Button onClick={() => editComment()} variant="contained">
            Edit Comment
        </Button>

        {
            activeComment !== null &&
            <div>
                <TextField
                    value={(activeComment) ? activeComment.content: ''}
                    label="Enter comment..."
                    onChange={(event) => { setActiveComment({...activeComment, content: event.currentTarget.value, }) }}
                />
                <DateTimeRangeSelector

                    onChange={(val) => setActiveComment(val)}

                    contextDateStart={activeComment.contextDateStart}
                    onChangeContextDateStart={val => activeComment.contextDateStart = val}

                    contextDateEnd={activeComment.contextDateEnd}
                    onChangeContextDateEnd={val => activeComment.contextDateEnd = val}

                    contextDateOnly={activeComment.contextDateOnly}
                    onChangeContextDateOnly={val => activeComment.contextDateOnly = val}

                    contextDateHasRange={activeComment.contextDateHasRange}
                    onChangeContextDateHasRange={val => activeComment.contextDateHasRange = val}

                    />
                <Button onClick={() => clearComment()} variant="contained">
                    Cancel
                </Button>
                <Button color='primary' onClick={() => httpPostJson('my-url', activeComment, () => console.log('saved'))} variant="contained" >
                    <SaveIcon/> Save
                </Button>
            </div>
        }    
    </div>
    );
}
Shubham Khatri

useEffectエフェクトをいつ実行するかを示す2番目の引数を取ります。状態が更新されたときに実行されるように、状態値を渡すことができます。またuseEffect、コードに複数のフックを含めることができます

const [propA, setPropA] = useState(props.propA);
const [propB, setPropB] = useState(props.propB);

useEffect(() => { 
  props.onChangePropA(propA); 
}, [propA]);

useEffect(() => { 
  props.onChangePropB(propB); 
}, [propB]);
<div>
  <button onClick={e => {setPropA(e.target.value)}}>Prop A</button>
  <button onClick={e => {setPropB(e.target.value)}}>Prop B</button>
</div>

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

子コンポーネントの反応フックでボタンがクリックされたときに、親コンポーネントの関数を使用するにはどうすればよいですか?

分類Dev

反応ネイティブプッシュ通知ステータスバーアイコンを変更するにはどうすればよいですか?

分類Dev

コンポーネントからコントローラーのプロパティを変更するにはどうすればよいですか?

分類Dev

コンポーネントからコントローラーのプロパティを変更するにはどうすればよいですか?

分類Dev

反応ネイティブGridViewコンポーネントの可視性状態を変更するにはどうすればよいですか?

分類Dev

Vue.jsのコードでコンポーネントプロパティの値を変更するにはどうすればよいですか?

分類Dev

Vue親を持つコンポーネントとそれ自体にプロパティを設定するにはどうすればよいですか?[警告]

分類Dev

角のある材料要素/コンポーネントのプロパティを変更するにはどうすればよいですか?

分類Dev

コンポーネントのプロパティでDPI対応の値を使用するにはどうすればよいですか?

分類Dev

フックとブートストラップに反応して、アコーディオンが開いたときにシェブロンを変更するにはどうすればよいですか?

分類Dev

反応:子コンポーネント(クラスコンポーネントではなく関数コンポーネント)の状態を親から変更するにはどうすればよいですか?

分類Dev

反応ネイティブでコンポーネントロジックを他のコンポーネントとクリーンな方法で共有するにはどうすればよいですか?

分類Dev

関数内のコンポーネントのプロパティを変更するにはどうすればよいですか?

分類Dev

Reactのコンポーネントのプロパティを変更するにはどうすればよいですか?

分類Dev

入力テキストが変更されたときにvue.jsでコンポーネントのプロパティを使用するにはどうすればよいですか?

分類Dev

SWTでコンポーネントの親を変更するにはどうすればよいですか?

分類Dev

ReactNativeでコンポーネントの親を変更するにはどうすればよいですか?

分類Dev

反応ネイティブでフェッチ応答のボタンテキストを変更するにはどうすればよいですか?

分類Dev

変数として渡されたreactコンポーネントにプロパティを追加するにはどうすればよいですか?

分類Dev

反応ネイティブで下部タブナビゲーターの画面を変更するときにアイコンとテキストの色を変更するにはどうすればよいですか?

分類Dev

TypeScriptを使用して別のプロパティに応じてReactコンポーネントの2つのプロパティをオプションとして設定するにはどうすればよいですか?

分類Dev

反応ネイティブの別のコンポーネントでrefを使用するにはどうすればよいですか?

分類Dev

すべての要素にクラスを適用せずに、単一の反応コンポーネントですべてのマテリアルUIタイポグラフィコンポーネントのスタイルを変更するにはどうすればよいですか?

分類Dev

フックを使用するようにReactコンポーネントを変更するにはどうすればよいですか?

分類Dev

反応するネイティブコンポーネントで2つの画像を交互にするにはどうすればよいですか

分類Dev

反応するネイティブコンポーネントで2つの画像を交互にするにはどうすればよいですか

分類Dev

プロパティファイルに応じてクライアントのURLを変更するにはどうすればよいですか?

分類Dev

Reactjsで再利用可能なコンポーネントを呼び出すときにプロパティの値を変更するにはどうすればよいですか?

分類Dev

サードパーティのライブラリからイベントがトリガーされたときに状態を変更するようにReactコンポーネントに指示するにはどうすればよいですか?

Related 関連記事

  1. 1

    子コンポーネントの反応フックでボタンがクリックされたときに、親コンポーネントの関数を使用するにはどうすればよいですか?

  2. 2

    反応ネイティブプッシュ通知ステータスバーアイコンを変更するにはどうすればよいですか?

  3. 3

    コンポーネントからコントローラーのプロパティを変更するにはどうすればよいですか?

  4. 4

    コンポーネントからコントローラーのプロパティを変更するにはどうすればよいですか?

  5. 5

    反応ネイティブGridViewコンポーネントの可視性状態を変更するにはどうすればよいですか?

  6. 6

    Vue.jsのコードでコンポーネントプロパティの値を変更するにはどうすればよいですか?

  7. 7

    Vue親を持つコンポーネントとそれ自体にプロパティを設定するにはどうすればよいですか?[警告]

  8. 8

    角のある材料要素/コンポーネントのプロパティを変更するにはどうすればよいですか?

  9. 9

    コンポーネントのプロパティでDPI対応の値を使用するにはどうすればよいですか?

  10. 10

    フックとブートストラップに反応して、アコーディオンが開いたときにシェブロンを変更するにはどうすればよいですか?

  11. 11

    反応:子コンポーネント(クラスコンポーネントではなく関数コンポーネント)の状態を親から変更するにはどうすればよいですか?

  12. 12

    反応ネイティブでコンポーネントロジックを他のコンポーネントとクリーンな方法で共有するにはどうすればよいですか?

  13. 13

    関数内のコンポーネントのプロパティを変更するにはどうすればよいですか?

  14. 14

    Reactのコンポーネントのプロパティを変更するにはどうすればよいですか?

  15. 15

    入力テキストが変更されたときにvue.jsでコンポーネントのプロパティを使用するにはどうすればよいですか?

  16. 16

    SWTでコンポーネントの親を変更するにはどうすればよいですか?

  17. 17

    ReactNativeでコンポーネントの親を変更するにはどうすればよいですか?

  18. 18

    反応ネイティブでフェッチ応答のボタンテキストを変更するにはどうすればよいですか?

  19. 19

    変数として渡されたreactコンポーネントにプロパティを追加するにはどうすればよいですか?

  20. 20

    反応ネイティブで下部タブナビゲーターの画面を変更するときにアイコンとテキストの色を変更するにはどうすればよいですか?

  21. 21

    TypeScriptを使用して別のプロパティに応じてReactコンポーネントの2つのプロパティをオプションとして設定するにはどうすればよいですか?

  22. 22

    反応ネイティブの別のコンポーネントでrefを使用するにはどうすればよいですか?

  23. 23

    すべての要素にクラスを適用せずに、単一の反応コンポーネントですべてのマテリアルUIタイポグラフィコンポーネントのスタイルを変更するにはどうすればよいですか?

  24. 24

    フックを使用するようにReactコンポーネントを変更するにはどうすればよいですか?

  25. 25

    反応するネイティブコンポーネントで2つの画像を交互にするにはどうすればよいですか

  26. 26

    反応するネイティブコンポーネントで2つの画像を交互にするにはどうすればよいですか

  27. 27

    プロパティファイルに応じてクライアントのURLを変更するにはどうすればよいですか?

  28. 28

    Reactjsで再利用可能なコンポーネントを呼び出すときにプロパティの値を変更するにはどうすればよいですか?

  29. 29

    サードパーティのライブラリからイベントがトリガーされたときに状態を変更するようにReactコンポーネントに指示するにはどうすればよいですか?

ホットタグ

アーカイブ