0

I'm beginner of react-native. I'm making music platform Application with my team.

I have a question. For example, when i search data in Screen1.

and i want to show related detailed data in Screen2.

but detailed data is stored in my db. so, i should async communication with my server.

But i don't know when i call function is better.

I make getData() function.

shortly example,

In Screen1

<TouchableOpacity onPress={() =>{getData(); navigate('Screen2');}} /> 

or

In Screen2

useEffect(() => {
    getData();
,[]}

My App case is here

(Screen1)

 <View>
                    <FlatList
                          numColumns ={2}
                          data={state.data}
                          keyExtractor={posts => posts.id}
                          onEndReached={onEndReached}
                          onEndReachedThreshold={0.8}
                          ListFooterComponent={loading && <ActivityIndicator />}
                          renderItem={({item}) =>{
                          return (
                           <View style ={{margin:'9%',}}>
                              <TouchableOpacity onPress={()=>{getCuration({isSong,object:item,id:item.id}); navigate('SelectedCuration', {id: item.id}); }}>
                                  <View style={styles.post}>
                                      <View style={{width:130, height:130}}>
                                          <Imagetake url={item.attributes.artwork.url}></Imagetake>
                                      </View>
                                      <View>
                                         <View>
                                              <Text>{item.attributes.name.split("(feat.")[0]}</Text>
                                              { item.attributes.name.split("(feat.")[1] ?
                                              <Text>feat. {item.attributes.name.split("(feat.")[1].slice(0,-1)}</Text> :
                                              null}
                                              <Text>{item.attributes.artistName}</Text>

                                         </View>
                                      </View>
                                   </View>
                              </TouchableOpacity>
                            </View>
                           )
                           }}
                     />
</View>

(Screen2)

import React, { useContext, useEffect, useState , Component} from 'react';
import { View, Text, Image, Button, StyleSheet,ActivityIndicator ,TextInput, SafeAreaView, TouchableOpacity, FlatList } from 'react-native';
import { Context as CurationContext } from '../../context/CurationContext';
import { Context as UserContext } from '../../context/UserContext';
import { Context as PlaylistContext } from '../../context/PlaylistContext';
import { Context as DJContext } from '../../context/DJContext';
import {Rating} from 'react-native-elements';
import { navigate } from '../../navigationRef';
import Modal from 'react-native-modal';

const Imagetake = ({url}) => {
    url =url.replace('{w}', '500');
    url = url.replace('{h}', '500');
    return (

    <Image style ={{borderRadius :10 , height:'100%', width:'100%'}} source ={{url:url}}/>

    );
};

const SelectedCuration = ({navigation}) => {
    const {state, postCuration, getmyCuration, deleteCuration, getCurationposts, likecurationpost,unlikecurationpost} = useContext(CurationContext);
    const { state: userState, getMyCurating, getOtheruser } = useContext(UserContext);
    const { getUserPlaylists } = useContext(PlaylistContext);
    const { getSongs } = useContext(DJContext);
    const [ispost, setIspost] = useState(false);
    const [text, setText] = useState('');
    const [showModal, setShowModal] = useState(false);
    const [number, setNumber] = useState(0);
    const curationid= navigation.getParam('id');
    console.log('SelectedCuration Page');
    const onClose =() => {
        setShowModal(false);
    }

    return (
        <SafeAreaView style={{flex:1}}>
          {state.currentCuration.songorartistid == undefined || (state.currentCuration.songorartistid !=curationid) ? <ActivityIndicator/> :

          <View style={{flex:1 , backgroundColor:'#fff'}}>
              <View style={{flex:2.5}}>

                   <View style={{flex:2}}>

                       <View style={{flex:1 , flexDirection:'row'}}>
                          <View style= {{flex:3, justifyContent: 'center', alignItems:'center'}}>
                              <View style={{ borderRadius:50,width:100, height:100, backgroundColor:'#666', marginBottom:'10%'}}>
                                {state.currentCuration.isSong ? <Imagetake url={state.currentCuration.object.attributes.artwork.url}></Imagetake> : null}
                              </View>
                              <Text>{state.currentCuration.object.attributes.name}</Text>
                          </View>
                          <View style = {{flex:5, marginLeft:'10%',justifyContent:'center', alignItems:'flex-start'}}>
                              {state.currentCuration.participate.length==0
                              ?
                              <Text style={{marginBottom:'5%'}}>별점  0</Text>
                               :
                              <Text style={{marginBottom:'5%'}}>별점  {(state.currentCuration.rating/state.currentCuration.participate.length).toFixed(2)}</Text>
                              }
                              <Text style={{marginBottom:'5%'}}>큐레이션에 참여한사람  {state.currentCuration.participate.length}</Text>
                          </View>
                       </View>
                  </View>

              </View>
              <View style={{flex:1.7}}>
                {state.currentCuration.participate.includes(userState.myInfo._id) ?
                     <Button
                         title = "나의 큐레이션 보기"
                         color ='#E73177'
                         onPress ={() => {
                                setShowModal(true);
                                getmyCuration({id:state.currentCuration.songorartistid})
                        }}
                     />
                    :
                    <View style={{flex:1.7}}>
                     {ispost ?
                                      <View style={{flex:1.7}}>
                                          <View style={{flex:2, justifyContent:'center', marginBottom:'5%', alignItems:'center'}}>
                                            <TextInput
                                              style={styles.inputBox}
                                              value = {text}
                                              onChangeText={text=>setText(text)}
                                              placeholder="큐레이션 내용"
                                              multiline={true}
                                              autoCapitalize='none'
                                              autoCorrect={false}
                                              placeholderTextColor ="#888888"
                                              keyboardType = "email-address"
                                            />
                                            <Rating
                                                type='heart'
                                                ratingCount={5}
                                                startingValue={0}
                                                imageSize={30}
                                                onFinishRating={(value)=>{setNumber(value);}}
                                             />
                                          </View>
                                          <View style={{flex:1, flexDirection:'row', justifyContent:'center'}}>
                                              <Button
                                                  title = "큐레이션 작성"
                                                  color ='#E73177'
                                                  onPress ={() => {
                                                      postCuration({isSong:state.currentCuration.isSong , rating:number, object:state.currentCuration.object, textcontent:text, id:state.currentCuration.songorartistid})
                                                      getMyCurating();
                                                      setIspost(false);
                                                      setText('');
                                                  }}
                                              />
                                              <Button
                                                  title = "큐레이션 취소"
                                                  color ='#E73177'
                                                  onPress ={() => {
                                                      setIspost(false);
                                                      setText('');
                                                  }}
                                              />
                                          </View>
                                      </View>
                                :
                              <Button
                                  title = "큐레이션 작성하기"
                                  color ='#E73177'
                                  onPress ={() => {
                                         setIspost(true);

                                 }}
                              />
                                }</View>
                 }
              </View>

              <View style={{flex:5}}>
                   <FlatList
                       data={state.currentCurationpost}
                       keyExtractor={comment => comment._id}
                       renderItem={({item}) =>{
                       return (
                            <View style={{flex:1}}>
                                <View style ={{flex:1, flexDirection:'row'}}>
                                    <TouchableOpacity onPress={() => {
                                        if(item.postUserId == userState.myInfo._id){
                                            navigate('Account');
                                        }else{
                                            getUserPlaylists({id:item.postUserId}); 
                                            getOtheruser({id:item.postUserId}); 
                                            getSongs({id:item.postUserId});
                                            getCurationposts({id: item.postUserId}); 
                                            navigate('OtherAccount');
                                        }}}>
                                        <Text>작성자 {item.postuser}</Text>
                                    </TouchableOpacity>
                                                { item.likes.includes(userState.myInfo._id) ?
                                                <TouchableOpacity style={styles.end} onPress={()=>{ unlikecurationpost({id:item._id, songorartistid:item.songorartistid});}} >
                                                    <Text>♥︎</Text>
                                                </TouchableOpacity> :
                                                <TouchableOpacity style={styles.end} onPress={()=>{  likecurationpost({id:item._id, songorartistid:item.songorartistid});}}>
                                                    <Text>♡</Text>
                                                </TouchableOpacity> }
                                      <Text style>{item.likes.length}개</Text>
                                </View>
                                <View style ={{flex:2, flexDirection:'row'}}>
                                    <Text>{item.textcontent}</Text>
                                </View>
              {showModal ?
                            <Modal
                                isVisible={true}
                                onBackdropPress={onClose}
                                backdropOpacity={0.1}
                                style={{justifyContent:'flex-end', margin:0,}}>

                                <View style={{flex:0.5, backgroundColor:'#fff'}}>
                                   {state.mycurationpost.likes == undefined ?
                                   <ActivityIndicator/> :
                                   <View>
                                    <View>
                                        <Text>작성자 {state.mycurationpost.postuser}</Text>
                                        <Text>{state.mycurationpost.textcontent}</Text>
                                        <Text>좋아요 {state.mycurationpost.likes.length}</Text>
                                    </View>
                                    <View style={{flexDirection:'row', justifyContent:'center'}}>
                                        <Button
                                            title = "큐레이션 지우기"
                                            color ='#E73177'
                                            onPress ={() => {
                                                setShowModal(false);
                                                deleteCuration({id:item._id})
                                                getMyCurating();
                                            }}
                                        />

                                    </View>

                                   </View>
                                   }

                                </View>
                            </Modal>
                            :null
              }
                            </View>

                        );
                       }}
                    />
              </View>

          </View>


          }

        </SafeAreaView>

    );
};



const styles = StyleSheet.create({
    inputBox : {
        borderWidth:0.8,
        borderRadius:5,
        borderColor : "#F4D726",
        width:'80%',
        height: '100%',
    },

});

export default SelectedCuration ;

Curation Context is

import AsyncStorage from '@react-native-community/async-storage';
import createDataContext from './createDataContext';
import serverApi from '../api/serverApi';
import { navigate } from '../navigationRef';

const curationReducer = (state, action) => {
    switch(action.type) {
        case 'get_curation':
            return { ...state,  currentCuration: action.payload[0], currentCurationpost:action.payload[1] };
        case 'get_curationposts':
            return { ...state, curationposts:action.payload };
        case 'init_curationposts':
            return { ...state, curationposts:action.payload };
        case 'get_mycuration':
            return { ...state, mycurationpost:action.payload };
        case 'post_curation':
            return { ...state,  currentCuration: action.payload[0], currentCurationpost: [...state.currentCurationpost, action.payload[1]] };
        case 'like_curationpost':
            return { ...state,  currentCuration: action.payload[0], currentCurationpost:action.payload[1] };

        default:
            return state;
    }
};

const postCuration = dispatch => {
    return async ({ isSong, object, textcontent, id, rating }) => {
        try {
            const response = await serverApi.post('/curationpost/'+id, { isSong, object, textcontent, rating });
            dispatch({ type: 'post_curation', payload: response.data });
        }
        catch(err){
            dispatch({ type: 'error', payload: 'Something went wrong with postCuration' });
        }
    }
};

const deleteCuration = dispatch => {
    return async ({id}) => {
        try {
            const response = await serverApi.delete('/curationpost/'+id);
            dispatch({ type: 'get_curation', payload: response.data });
        }
        catch(err){
            dispatch({ type: 'error', payload: 'Something went wrong with deleteCuration' });
        }
    }
};

const likecurationpost = dispatch => {
    return async ({id, songorartistid}) => {
        try {
            const response = await serverApi.post('/curationpostlike/'+id+'/'+songorartistid);
            dispatch({ type: 'like_curationpost', payload: response.data });
        }
        catch(err){
            dispatch({ type: 'error', payload: 'Something went wrong with likecurationpost' });
        }
    }
};

const unlikecurationpost = dispatch => {
    return async ({id, songorartistid}) => {
        try {
            const response = await serverApi.delete('/curationpostlike/'+id+'/'+songorartistid);
            dispatch({ type: 'like_curationpost', payload: response.data });
        }
        catch(err){
            dispatch({ type: 'error', payload: 'Something went wrong with unlikecurationpost' });
        }
    }
};

const initcurationposts = dispatch => {
    return async () => {
        try {
            dispatch({ type: 'init_curationposts', payload: null });
        }
        catch(err){
            dispatch({ type: 'error', payload: 'Something went wrong with initcurationposts' });
        }
    }
};

const getCuration = dispatch => {
    return async ({isSong,object,id}) => {
        try {
            const response = await serverApi.post('/curation/'+id, {isSong,object});
            dispatch({ type: 'get_curation', payload: response.data });
        }
        catch(err){
            dispatch({ type: 'error', payload: 'Something went wrong with getCuration' });
        }
    }
};

const getCurationposts = dispatch => {
    return async ({ id }) => {
        try {
            const response = await serverApi.get('/curationposts/'+id);
            dispatch({ type: 'get_curationposts', payload: response.data });
        }
        catch(err){
            dispatch({ type: 'error', payload: 'Something went wrong with getCurationposts' });
        }
    }
};

const getmyCuration = dispatch => {
    return async ({ id }) => {
        try {
            const response = await serverApi.get('/mycurationpost/'+id);
            dispatch({ type: 'get_mycuration', payload: response.data });
        }
        catch(err){
            dispatch({ type: 'error', payload: 'Something went wrong with getmyCuration' });
        }
    }
};

export const { Provider, Context } = createDataContext(
    curationReducer,
    { postCuration, deleteCuration, likecurationpost,unlikecurationpost, 
        initcurationposts, getCuration, getCurationposts, getmyCuration },
    { currentCuration:{}, currentCurationpost:[], mycurationpost:{}, curationposts:null, errorMessage: ''}
)

Curation Routes in Server

const express = require('express');
const mongoose = require('mongoose');
const Curation = mongoose.model('Curation');
const Curationpost = mongoose.model('CurationPost');
const User = mongoose.model('User');
const Notice = mongoose.model('Notice');

const requireAuth = require('../middlewares/requireAuth');
var admin = require('firebase-admin');
const router = express.Router();
require('date-utils');
router.use(requireAuth);

router.get('/user', async(req, res) => {
       const user= await User.findOne({email : req.user.email});
       res.send(user);
});

//post Curation
router.post('/curationpost/:id', requireAuth, async (req, res) =>{
    const { isSong, object, textcontent, rating } = req.body;
    var newDate = new Date()
    var time = newDate.toFormat('YYYY-MM-DD HH24:MI:SS');
    try {
        const curationpost = new Curationpost({ isSong, object, rating, postUser: req.user.name, postUserId: req.user._id, time, textcontent, songorartistid:req.params.id });
        await curationpost.save();
        const curation = await Curation.findOneAndUpdate({ songorartistid:req.params.id }, {$push: { participate:req.user._id }, $inc : { rating:rating }}, {new:true});
        res.send([curation, curationpost]);
    } catch (err) {
        return res.status(422).send(err.message);
    }
});

// delete Curation
router.delete('/curationpost/:id', async (req, res) =>{
    try {
        const curationpost = await Curationpost.findOneAndDelete({_id:req.params.id});
        const curationposts = await Curationpost.find({songorartistid:curationpost.songorartistid});
        const curation = await Curation.findOneAndUpdate({songorartistid:curationpost.songorartistid},{$pull:{participate:curationpost.postUserId}, $inc:{rating:-1*curationpost.rating}}, {new:true});
        res.send([curation, curationposts]);
    } catch (err) {
        return res.status(422).send(err.message);
    }
});

// like Curation post
router.post('/curationpostlike/:id/:songorartistid', requireAuth, async(req,res) =>{
    var newDate = new Date()
    var noticeTime = newDate.toFormat('YYYY-MM-DD HH24:MI:SS');
    try{
        const curation = await Curation.findOne({songorartistid:req.params.songorartistid});
        const curationpost =  await Curationpost.findOneAndUpdate({_id : req.params.id}, {$push : {likes : req.user._id}}, {new:true});
        const curationposts = await Curationpost.find({songorartistid:req.params.songorartistid});
        if(curationpost.postUserId.toString() != req.user._id.toString()){
            try {
                const notice  = new Notice({ noticinguser:req.user._id, noticieduser:curationpost.postUserId, noticetype:'culike', time: noticeTime, curationpost:curationpost._id });
                await notice.save();
            } catch (err) {
                return res.status(422).send(err.message);
            }
        }
        res.send([curation, curationposts]);
        const targetuser = await User.findOne({_id:curationpost.postUserId});

        if( targetuser.noticetoken != null  && targetuser._id.toString() != req.user._id.toString()){
            var message = {
                notification : {
                    title: curation.object.attributes.artistName + ' - ' + curation.object.attributes.name,
                    body : req.user.name + '님이 큐레이션을 좋아합니다.',
                },
                token : targetuser.noticetoken
            };
            try {
                await admin.messaging().send(message).then((response)=> {}).catch((error)=>{console.log(error);});
            } catch (err) {
                return res.status(422).send(err.message);
            }
        }
    }catch(err){
        return res.status(422).send(err.message);
    }
});

// unlike Curation post
router.delete('/curationpostlike/:id/:songorartistid', requireAuth, async(req,res) =>{
    try{
        const curation = await Curation.findOne({songorartistid:req.params.songorartistid});
        const curationpost =  await Curationpost.findOneAndUpdate({_id : req.params.id}, {$pull : {likes : req.user._id}}, {new:true});
        const curationposts = await Curationpost.find({songorartistid:req.params.songorartistid});
        await Notice.findOneAndDelete({$and: [{ curation:curation._id }, { curationpost:curationpost._id }, { noticinguser:req.user._id }, { noticetype:'culike' }, { noticieduser:curationpost.postUserId }]});
        res.send([curation, curationposts]);
    }catch(err){
        return res.status(422).send(err.message);
    }
});

// getCuration
router.post('/curation/:id', async (req, res) =>{
    const { isSong, object } = req.body;
    try {
        const check = await Curation.findOne({songorartistid:req.params.id});
        if (check == null){
            const curation = new Curation({isSong, object, songorartistid:req.params.id});
            await curation.save();
            const curationpost = await Curationpost.find({songorartistid:req.params.id});
            res.send([curation,curationpost]);
        }else {
            const curationpost = await Curationpost.find({songorartistid:req.params.id});
            res.send([check,curationpost]);
        }
    } catch (err) {
        return res.status(422).send(err.message);
    }
});

// get user curationposts
router.get('/curationposts/:id', async (req, res) =>{
    try {
        const curationpost = await Curationpost.find({postUserId:req.params.id});
        res.send(curationpost);
    } catch (err) {
        return res.status(422).send(err.message);
    }
});

// get MyCuration
router.get('/mycurationpost/:id/', requireAuth, async (req, res) =>{
    try {
        const curationpost = await Curationpost.findOne({$and :[{ songorartistid: req.params.id }, { postUserId: req.user._id }]});
        res.send(curationpost);
    } catch (err) {
        return res.status(422).send(err.message);
    }
});

module.exports = router;

So, My app is still waiting when state.currentContent gets. getCuration() is function to get state.currentContent.

So My Question is

  1. put getData() func in Screen1 when navigate screen2
  2. put getData() func in Screen2 useEffect

problem is getData(in this case getCuration) is Context function(useContext) ?? So, in first solution, when i go to screen2, screen1 is re rendering. in second solution, getData() is little later than solution 1. So, data is loading longer when people feel i think.

which is better?? help me plz...

1 Answers1

0

There are some solutions that can help you access this state fast The trick is to make it global and then access them wherever you are in your entire app. You will just make a request from your main screen and check if the state changes or not, so if Screen1 is the first to be displayed in your app, just put this logic inside. You can

  1. use AsynchStorage: which is asynchronous encrypted but I think a bit complex than
  2. use useGlobal: it's synchronous in term of speediness to access data it's the best one
  3. Use Redux: more complex if your app is not so big

Find the documentation here

https://www.npmjs.com/package/reactn https://github.com/react-native-async-storage/async-storage https://code.tutsplus.com/tutorials/using-redux-in-a-react-native-app--cms-36001

pacy.eth
  • 175
  • 2
  • 9
  • Thanks for your help. but, my function is made by reducer already. I upload Curation Context + Curation routes(server). in this case, can i apply as you said?? – 흑수의 세상 Mar 10 '21 at 15:18