In this project, we will build a simple social media application using React Native. This app will allow users to create posts, view a feed of posts, and interact with posts by liking them. This project will help you consolidate your knowledge of React Native components, state management, navigation, and networking.

Objectives

  • Create a user interface for a social media feed.
  • Implement navigation between different screens.
  • Manage state for posts and user interactions.
  • Fetch and display data from a mock API.
  • Handle user input and form submissions.

Prerequisites

Before starting this project, ensure you have completed the previous modules and have a good understanding of:

  • React Native components and styling.
  • State and lifecycle methods.
  • React Navigation.
  • Fetching data from APIs.

Project Structure

  1. Setting Up the Project
  2. Creating the Feed Screen
  3. Creating the Post Screen
  4. Implementing Navigation
  5. Fetching and Displaying Posts
  6. Handling User Interactions
  7. Styling the App

  1. Setting Up the Project

First, let's set up a new React Native project.

npx react-native init SocialMediaApp
cd SocialMediaApp
npm install @react-navigation/native @react-navigation/stack
npm install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

Ensure you have the necessary dependencies installed for React Navigation.

  1. Creating the Feed Screen

Create a new file FeedScreen.js in the src/screens directory.

// src/screens/FeedScreen.js
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, StyleSheet, TouchableOpacity } from 'react-native';

const FeedScreen = ({ navigation }) => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    // Fetch posts from a mock API
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(data => setPosts(data));
  }, []);

  return (
    <View style={styles.container}>
      <FlatList
        data={posts}
        keyExtractor={item => item.id.toString()}
        renderItem={({ item }) => (
          <TouchableOpacity onPress={() => navigation.navigate('Post', { post: item })}>
            <View style={styles.post}>
              <Text style={styles.title}>{item.title}</Text>
              <Text style={styles.body}>{item.body}</Text>
            </View>
          </TouchableOpacity>
        )}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
  },
  post: {
    marginBottom: 15,
    padding: 15,
    backgroundColor: '#fff',
    borderRadius: 5,
    shadowColor: '#000',
    shadowOpacity: 0.1,
    shadowRadius: 5,
    elevation: 3,
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
  },
  body: {
    marginTop: 5,
    fontSize: 14,
    color: '#333',
  },
});

export default FeedScreen;

  1. Creating the Post Screen

Create a new file PostScreen.js in the src/screens directory.

// src/screens/PostScreen.js
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const PostScreen = ({ route }) => {
  const { post } = route.params;

  return (
    <View style={styles.container}>
      <Text style={styles.title}>{post.title}</Text>
      <Text style={styles.body}>{post.body}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
  },
  body: {
    marginTop: 10,
    fontSize: 16,
    color: '#333',
  },
});

export default PostScreen;

  1. Implementing Navigation

Set up navigation between the Feed and Post screens.

// src/navigation/AppNavigator.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import FeedScreen from '../screens/FeedScreen';
import PostScreen from '../screens/PostScreen';

const Stack = createStackNavigator();

const AppNavigator = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Feed">
        <Stack.Screen name="Feed" component={FeedScreen} />
        <Stack.Screen name="Post" component={PostScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default AppNavigator;

Update App.js to use the AppNavigator.

// App.js
import React from 'react';
import AppNavigator from './src/navigation/AppNavigator';

const App = () => {
  return <AppNavigator />;
};

export default App;

  1. Fetching and Displaying Posts

We have already implemented fetching posts in the FeedScreen. Ensure the data is displayed correctly in the FlatList.

  1. Handling User Interactions

Add a like button to each post and manage the state for likes.

// src/screens/FeedScreen.js
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, StyleSheet, TouchableOpacity, Button } from 'react-native';

const FeedScreen = ({ navigation }) => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(data => setPosts(data));
  }, []);

  const handleLike = (id) => {
    setPosts(posts.map(post => post.id === id ? { ...post, liked: !post.liked } : post));
  };

  return (
    <View style={styles.container}>
      <FlatList
        data={posts}
        keyExtractor={item => item.id.toString()}
        renderItem={({ item }) => (
          <TouchableOpacity onPress={() => navigation.navigate('Post', { post: item })}>
            <View style={styles.post}>
              <Text style={styles.title}>{item.title}</Text>
              <Text style={styles.body}>{item.body}</Text>
              <Button
                title={item.liked ? 'Unlike' : 'Like'}
                onPress={() => handleLike(item.id)}
              />
            </View>
          </TouchableOpacity>
        )}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
  },
  post: {
    marginBottom: 15,
    padding: 15,
    backgroundColor: '#fff',
    borderRadius: 5,
    shadowColor: '#000',
    shadowOpacity: 0.1,
    shadowRadius: 5,
    elevation: 3,
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
  },
  body: {
    marginTop: 5,
    fontSize: 14,
    color: '#333',
  },
});

export default FeedScreen;

  1. Styling the App

Ensure the app is visually appealing by refining the styles.

// src/screens/FeedScreen.js
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
    backgroundColor: '#f0f0f0',
  },
  post: {
    marginBottom: 15,
    padding: 15,
    backgroundColor: '#fff',
    borderRadius: 5,
    shadowColor: '#000',
    shadowOpacity: 0.1,
    shadowRadius: 5,
    elevation: 3,
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
  },
  body: {
    marginTop: 5,
    fontSize: 14,
    color: '#333',
  },
});

Conclusion

In this project, you have built a basic social media app with React Native. You have learned how to:

  • Set up a React Native project.
  • Create and navigate between screens.
  • Fetch and display data from an API.
  • Handle user interactions and manage state.
  • Style the app to make it visually appealing.

This project serves as a foundation for more complex social media applications. You can extend this project by adding features such as user authentication, comments, and more advanced state management with Redux or Context API.

© Copyright 2024. All rights reserved