ランサーズ等のサービスを開発・運用する中で得た知識やノウハウを紹介しています。

thumbnail

Labels:  JavaScript 投稿者:takepo

React × Redux で action 発行時に確認ダイアログを挟む middleware の実装例

pookチームのtakepoです。
今回は、React × Redux でstateを変更する時にダイアログ等で確認表示を挟みたいときの良い方法をご紹介します。
その場合の例として、「ユーザーの情報を更新するとき、更新しても良いかを一度確認するダイアログ表示する」といったことが挙げられます。

この方法を一言で言うと、
「Container側では変更処理をするactionのみ呼び出すようにする」
です。
サンプルを交えてご紹介します。

サンプル

データを更新する際に確認用のダイアログを表示し、「OK」を選択した場合に更新処理を行います。

Dialog Component

ダイアログのcomponentはこのような形で作成しておきます。
※今回はMaterial-UIを使用し、シンプルな作りにしています。

class Dialog extends Component {
    props: {
        openFlag: boolean;
        message: string;
        title: string;
        okClickHandler: Function;
    };

    renderDialogButtons(): React.Element<*> {
        return (
            <div>
                <RaisedButton
                    label="キャンセル"
                    onClick={/* ダイアログを閉じる処理 */}
                />
                <RaisedButton
                    label="OK"
                    onClick={this.props.okClickHandler}
                />
            </div>
        );
    }

    render() {
        return (
            <Dialog
                title={this.props.title}
                open={this.props.openFlag}
                actions={this.renderDialogButtons()}
            >
                {this.props.message}
            </Dialog>
        );
    }
}

export default Dialog;

更新処理をするactionを呼ぶContainer

変更処理をかけるactionを呼ぶ箇所はこのように書きます。
ここで注目したいポイントは、更新処理をするactionの第2引数にmeta情報としてダイアログのpropsに渡すmessageとtitleを入れておくことです。


const payload = {
 // 更新する情報
}
const meta = {
  dialogInfo: {
    title: '更新',
    message: '情報を更新しますがよろしいですか?',
  },
}

// 更新処理をかけるaction
this.props.actions.update(payload, meta);

middleware

更新処理をするactionでmetaとして入れ込んだダイアログの情報を元に、ダイアログを開くときに必要なpayloadを作成します。そして、ダイアログを開くためのactionをnext()に渡します。
ここで注目したいポイントは、payloadのokClickHandlerに本来の変更処理を行うactionを入れ込むことです。


export default (store: any) => (next: any) => (action: any) => {
    if (action.meta && action.meta.dialogInfo) {
        const payload = {
            ...action.meta.dialogInfo,
            okClickHandler: () => {
                // このままactionを渡すとまた確認ダイアログを挟んでしまうので、dialogInfoを削除しておく
                delete action.meta.dialogInfo;
                next(action);
            },
        };

        // open() はダイアログを開くaction
        return next(open(payload));
    }

    return next(action);
};

まとめ

省いてしまっている部分もありますが、流れとしてはこのようになります。
middlewareをうまく利用することで
「Container側では変更処理をするactionのみ呼び出すようにする」
ことができました。
これで更新処理を呼ぶ側をすっきり書くことができます!

ランサーズではサービスを成長させてくれるエンジニア、デザイナーを募集しています!
ご興味がある方は、以下URLよりご応募ください。


【中途採用】
サービスリードエンジニア
テックリード(アーキテクト)
フロントエンドエンジニア
サーバーサイドエンジニア
業務エンジニア(社内システム基盤・基幹システム)

【インターン・学生バイト】
19新卒対象サマーインターン
エンジニアインターン

その他採用情報

関連記事

thumbnail
Expo でフォントのロードが終わってから render するには

森です。今は Expo と ReactNative と NativeBase を使っています。先程体験した問題とその対処を紹介します。 現象 console.error: “fontFamily ‘Ionicons’ is …

thumbnail
レスポンシブ対応の LP を簡単に作れるツールを React Redux で作った。ソースコードあり

pook チームの tsuyoshi です。レスポンシブ対応の LP を簡単に作れるツールへのニーズが社内で高まってきたので React Redux の練習がてら先日の開発合宿で作りました。社内でもランディングページの制作を依頼されたり、発注したりするわけです …

初心者に向けたサンプル付きReact入門と勉強法について

@takepo です。 先日、【サポーターズ勉強会】React入門 というイベントで再度登壇させていただきました。 その登壇の際のスライドをあげさせていただきます。 内容はReact初心者向けのものになっていて、コードサンプル付きで説明させていただきました。 …