React Native Redux 1

Date:

11 Oct 2019

What is the idea?

  • React Native is used to build Phone Apps using Web Technology

  • Redux is data management layer

  • In this example, we will build an AwesomeMovieApp with TikTok style:
    • Two pages: Home and Search

    • On home page, we can change to a random movie that is store in the state

    • The Search does nothing at the moment, just for testing!

Structure

../_images/React-Native-Redux-1-1.webp
  • AwesomeMovies: Directory automatically generated by expo init AwesomeMovies
    • app.js : we only modified this file among all auto-generated files

    • redux: the folder of all our custom code
      • components: react components
        • Navigator.js : the Main component that enable us to switch between Home and Search

        • Home.js : the Home component

        • Search.js

      • reducers: are state machines !
        • Home.js : the reducer for Home Component , handles all actions happened there and refreshes Home State

Install Dependencies

npm install -g expo-cli
expo init AwesomeMovies
cd AwesomeProject

expo install react-native-gesture-handler react-redux redux react-navigation-stack react-navigation

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

npm start --reset-cache

app.js

import React,{Component} from 'react'
import {createStore,combineReducers} from 'redux'
import {Provider} from 'react-redux'

import HomeReducer from './redux/reducers/Home'
const store = createStore(combineReducers({
    Home: HomeReducer,
    // you can add other reducers here
    // eg: Search: SearchReducer
}))

import Navigitor from './redux/components/Navigator'

export default class AwesomeMovies extends Component{
  render(){
    return(
      <Provider store={store}>
        <Navigitor/>
      </Provider>
    )
  }
}

components/Navigator.js

import {createAppContainer} from 'react-navigation'
import {createStackNavigator} from 'react-navigation-stack'

import Home from './Home'
import Search from './Search'

const Navigator = createStackNavigator({
    Home:{screen: Home},
    Search:{screen: Search}
})

export default createAppContainer(Navigator)

components/Home.js

import React,{Component} from 'react'
import {View,Text,Button} from 'react-native'
import {bindActionCreators} from 'redux'
import {connect} from 'react-redux'

class Home extends Component{
    render(){
        return(
            <View>
                <Text>{this.props.Home.currentMovie}</Text>
                <Button
                    title="changeMovie"
                    onPress={()=>this.props.changeMovie()}
                />
                <Text>This is Home</Text>
                <Button
                    title="Search"
                    onPress={()=>this.props.navigation.navigate('Search')}
                />
            </View>
        )
    }
}

//===============================
// Begin Actions
//===============================
const changeMovie = payload=>({
    type: "changeMovie",
    payload: payload
})
// End Actions

const mapStateToProps=(state)=>{
    const {Home}=state
    return {Home}
}
const mapActionToProps=action=>(
    bindActionCreators({changeMovie},action)
)
export default connect(mapStateToProps,mapActionToProps)(Home)

components/Search.js

import React,{Component} from 'react'
import {View,Text,Button} from 'react-native'

class Search extends Component{
    render(){
        return(
            <View>
                <Text>This is Search</Text>
                <Button
                    title="Home"
                    onPress={()=>this.props.navigation.navigate('Home')}
                />
            </View>
        )
    }
}

export default Search

reducers/Home.js

const initialState = {
    currentMovie:"Yui Hatano",
    movies:["Tsubasa Amami", "Yui Hatano"]
}

const HomeReducer = (state=initialState, action)=>{
    switch(action.type){
        case "changeMovie":
            var randomIndex = Math.floor(Math.random()*state.movies.length)
            return Object.assign({}, state, {
                currentMovie: state.movies[randomIndex]
              })
        default:
            return state
    }
}

export default HomeReducer