【问题标题】:React native) where should i fetch data from server more faster?React native)我应该在哪里更快地从服务器获取数据?
【发布时间】:2021-03-10 14:48:33
【问题描述】:

我是 react-native 的初学者。我正在和我的团队一起制作音乐平台应用程序。

我有一个问题。例如,当我在 Screen1 中搜索数据时。

我想在 Screen2 中显示相关的详细数据。

但详细数据存储在我的数据库中。所以,我应该与我的服务器进行异步通信。

但我不知道什么时候调用函数更好。

我制作了 getData() 函数。

简短的例子,

在屏幕 1 中

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

在屏幕 2 中

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

我的应用案例在这里

(屏幕 1)

 <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>

(屏幕2)

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 ;

策展上下文是

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: ''}
)

服务器中的管理路线

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;

所以,当 state.currentContent 获取时,我的应用仍在等待。 getCuration() 是获取 state.currentContent 的函数。

所以我的问题是

  1. 在 screen2 导航时将 getData() func 放入 Screen1
  2. 将getData()函数放入Screen2 useEffect

问题是getData(在这种情况下是getCuration)是上下文函数(useContext)?? 因此,在第一个解决方案中,当我转到 screen2 时,screen1 正在重新渲染。 在第二个解决方案中,getData() 比解决方案 1 稍晚。因此,当人们觉得我认为数据加载时间更长。

哪个更好??请帮帮我...

【问题讨论】:

    标签: mongodb react-native rendering use-context


    【解决方案1】:

    有一些解决方案可以帮助您快速访问此状态 诀窍是使其全球化,然后在整个应用程序中的任何位置访问它们。您只需从主屏幕发出请求并检查状态是否发生变化,因此如果 Screen1 是第一个显示在您的应用程序中的,只需将此逻辑放入其中。 你可以

    1. 使用AsynchStorage: 是异步加密的,但我觉得有点复杂
    2. 使用useGlobal:就访问数据的速度而言,它是同步的,这是最好的
    3. 使用 Redux:如果您的应用不是那么大,会更复杂

    在此处查找文档

    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

    【讨论】:

    • 感谢您的帮助。但是,我的功能已经由减速器完成。我上传策展上下文+策展路线(服务器)。这种情况,我可以按你说的申请吗??
    猜你喜欢
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 2017-10-21
    • 2017-06-19
    • 2012-01-18
    • 1970-01-01
    • 2020-07-12
    相关资源
    最近更新 更多