ReactNativeのFlatListの項目をクリックしてDetail画面へ移動する


いくつかのやり方があるかなと思いますが、ここではreact-navigationのStackNavigatorを利用してみます。
WebViewと連携した方が汎用性は高いのだろうけど、簡単なお知らせとかの定形情報提供を想定。

### 準備

必要なモジュールをインストールし、ファイルを作成します。

```
expo init home_detail
cd home_detail
yarn add react-navigator react-native-elements

mkdir screens
touch screens/Home.js screens/Detail.js
```

### App.js

Home.jsとDetail.jsを利用してStackNavigatorを作成します。

```js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';

//screenに置いたHomeとDetailを読み込み
import Home from './screens/Home';
import Detail from './screens/Detail';

//HomeとDetailをStackNavigatorとして構成する
const HomeStack = createStackNavigator(
    {
        Home: { screen: Home },
        Detail: { screen: Detail }
    }
);

//AppContainerを作る（V3から）
const HomeContainer = createAppContainer(HomeStack);

export default class App extends React.Component {
    render() {
        return (
            <HomeContainer />
        );
    }
}

```

### screens/Home.js


this.props.navigation.navigate('Detail', item)という感じで、Detailに値を渡せる。


```js
import React from 'react';
import { View, Text, FlatList } from 'react-native';
import { Card, ListItem, Button } from 'react-native-elements';

//リスト用データ（実際にはAPIから取得することになるかと）
const list = [
    { id: 1, name: 'user1', email: 'user1@test.com', memo: 'memo1' },
    { id: 2, name: 'user2', email: 'user2@test.com', memo: 'memo2' },
    { id: 3, name: 'user3', email: 'user3@test.com', memo: 'memo3' },
    { id: 4, name: 'user4', email: 'user4@test.com', memo: 'memo4' },
    { id: 5, name: 'user5', email: 'user5@test.com', memo: 'memo5' },
]

class Home extends React.Component {
    render() {
        return (
            <View style={{ flex: 1, paddingVertical: 20 }}>
                {/* 一覧表示 */}
                <FlatList
                    data={list}
                    keyExtractor={(item) => item.id.toString()}
                    renderItem={({ item }) => (
                        <ListItem
                            title={item.id + ' ' + item.name}
                            subtitle={item.email}
                            onPress={() => this.handleItemClick(item)}
                        />
                    )}
                />
            </View>
        );
    }

    handleItemClick = (item) => {
        //itemをDetailへ渡す
        this.props.navigation.navigate('Detail', item);
    }
}

export default Home;
```


### screens/Detail.js

const item = this.props.navigation.state.params;という感じでデータを受け取れます。
後は好きに表示するだけ。

```js
import React from 'react';
import { View, Text, FlatList } from 'react-native';
import { Card, ListItem, FormLabel, FormInput, Button } from 'react-native-elements';

class Detail extends React.Component {
    render() {

        //Homeから渡されたitemを受け取る（下記の様に受け取れる）
        const item = this.props.navigation.state.params;

        return (
            <View style={{ flex: 1, paddingVertical: 20 }}>
                <Card title='詳細データ'>
                    <FormLabel>ID</FormLabel>
                    <FormInput
                        value={item.id.toString()}
                        editable={false}
                    />
                    <FormLabel>Name</FormLabel>
                    <FormInput
                        value={item.name}
                        editable={false}
                    />
                    <FormLabel>Email</FormLabel>
                    <FormInput
                        value={item.email}
                        editable={false}
                    />
                    <FormLabel>Memo</FormLabel>
                    <FormInput
                        value={item.memo}
                        editable={false}
                    />
                    <Button
                        title='戻る'
                        onPress={() => this.props.navigation.navigate('Home')}
                        buttonStyle={{ marginTop: 20 }}
                    />
                </Card>
            </View>
        );
    }
}

export default Detail;
```