Reactで作ったリストに削除機能を作る
先日行った、もぐナビのスマートフォンユーザー向けページのUIを新しくした話を書きたいと思います。
もぐナビでは、"食べたい"商品を記録することが出来ます。 会員登録したユーザーは、マイページからこの記録を閲覧することが出来ます。 UIを新しくするタイミングで、jQueryで実装していたものをReact+TypeScriptにしました。
一覧を実装する
"食べたい"商品の一覧は、以下のようなものです。
食べたいの一覧をJSON形式で返却するエンドポイントへリクエストを行い、stateへ反映するようにしました。 stateにTabetaiItem型として定義した要素を保持する配列定義します。
interface TabetaiListState { items: TabetaiItem[], }
エンドポイントの内容をstateの配列へ追加することで、表示が更新されます。
load = (offset: number) => { const url = '/tabetailist' + '?offset=' + offset + '&limit=' + 20; fetch(url, { credentials: 'include' }) .then(response => { return response.json(); }) .then(json => { if (json.length == 0) { return; } this.setState(state => { const items = this.append(state.items, json); return { items: items, }; }); }) .catch(error => { }); }
要素を削除する機能を実装する
続いて、"食べたい"した商品を削除する機能を実装します。 jQueryで実装していたときは、以下のように実装していました。
$( '.close-button').click( function() { $(this).closest('li').remove() ; } ) ;
これをReactでどのように実装するか調べたところ、propsに関数を渡すことで実現できることがわかりました。 まず、要素を表示するコンポーネントのproppに、要素を削除する関数を定義します。
nterface TabetaiElementProp { onRemoveClick: any, }
要素を表示するコンポーネントでは、削除ボタンのクリックイベントで要素を削除する関数を実行するようにします。
render() { render() { return ( <li> <a className='close-button' onClick={() => this.props.onRemoveClick()}></a> <li/> ); } }
次に、一覧を表示するコンポーネントに要素を削除する関数を定義します。 クリックされた要素の位置をもとに、配列から該当する要素を削除し、stateへ反映します。
onRemoveClick = (index: number) => { let array = this.state.items; array.splice(index, 1); this.setState({ items: array }); } 配列から要素を作る際にpropsに関数を渡すことで、上で定義した関数が実行されるようになります。 render() { const list = this.state.items.map((item, index) => { return <TabetaiElement onRemoveClick={() => this.onRemoveClick(index)} />; }); return ( <ul> {list} </ul> ); }
まとめ
以上でリストに削除機能を作ることが出来ました。 propsに関数を渡すことで、子コンポーネントから親コンポーネントへイベントを伝搬することが出来ました。