繁体   English   中英

触发子组件在父组件中重新渲染

[英]Trigger child component to re-render in parent component

我正在使用 react-native 制作应用程序。 实现 onReserve() 时,我希望更新 ModalView。 但是它没有更新,Modalview 中 usermachine 的值与实现 onReserve() 之前的值相同。

让 usermachine 的第一个值为[]并在onReserve()之后将值更改为[{"id":"1"}] 但是Modalview上显示的usermachine仍然是[] ,再次实现onReserve()后让usermachine的值变为[{"id":"2"}] ,Modalview上显示的usermachine是[{"id":"1"}]

如何在onReserve()之后立即更新 Modalview 上显示的 usermachine 的值?

ReserveScreen.js

import React, {useEffect, useState, useRef} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StyleSheet,
  View,
  Alert,
  Button,
  Text,
  Modal,
  KeyboardAvoidingView,
} from 'react-native';
import ModalView from '../components/ModalView.js';
import MachineView from '../components/MachineView.js';
import AsyncStorage from '@react-native-async-storage/async-storage';

const ReserveScreen = ({navigation, route, category}) => {
  const [machines, setMachines] = useState([]);
  const [change1, setChange1] = useState(0); 
  function handlechange() {
    setChange1(change1 + 1);
  }

  const [loading, setLoading] = useState(0);
  const [loading2, setLoading2] = useState(0);

  const getmachineinfo = () => {
    setLoading2(loading2 + 1);
    fetch(
      'https://so6wenvyg8.execute-api.ap-northeast-2.amazonaws.com/dev/machine',
      {
        method: 'GET',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
      },
    )
      .then(response => response.json())
      .then(json => {
        let machinelist = [];
        for (let k = 0; k < json.machinearr.length; k++) {
          let id1 = -1;
          let name1 = '';
          let category1 = -1;
          let waitnum1 = -1;
          for (let i = 0; i < json.machinearr[k].length - 1; i++) {
            switch (i) {
              case 0:
                id1 = Number(json.machinearr[k][i]);
                break; //machineid
              case 1:
                name1 = json.machinearr[k][i];
                break; //machinename
              case 2:
                category1 = Number(json.machinearr[k][i]);
                break; //machinecategory
              case 3:
                continue; //machineimage
              case 4:
                waitnum1 = json.machinearr[k][i].length;
                break; //waitnumber
            }
          }
          let object = {
            name: name1,
            id: id1,
            waitnum: waitnum1,
            category: category1,
          };
          machinelist.push(object);
        }
        setMachines(machinelist);
        setTimeout(() => {
          setLoading(loading+1);
        }, 1000);
      })
      .catch(error => {
        console.error(error);
        return -1;
      });
  };
  useEffect(() => {
    console.log('useeffect');
    getmachineinfo();
  }, [change1]); 

  const [username, setUsername] = useState(''); 
  

  const getusername = async () => {
    try {
      const name = await AsyncStorage.getItem('@storage_username');
      setUsername(name);
      return;
    } catch (e) {
      console.log(e);
    }
  };
  getusername();
  
  const [userid,setUserid]=useState('');
  const getuserid= async()=>{
    const value = await AsyncStorage.getItem('@storage_userid');
    if (value !== null){
        setUserid(value);
    }
  }
  getuserid();
  
  const [myres, setMyres] = useState([]);
  const [loading3, setLoading3] = useState(0);
  const [loading4, setLoading4] = useState(0);
  const [usermachine, setUserMachine] = useState([]);

  const myReserve = () => {
          if (userid !== null) {
        const url =
          'https://so6wenvyg8.execute-api.ap-northeast-2.amazonaws.com/dev/reservation?userid=' +
          userid;
        fetch(url, {
          method: 'GET',
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
          },
        })
          .then(response => response.json())
          .then(json => {
            Alert.alert(JSON.stringify(json));
            setMyres(json["reservation"]);
            setUserMachine(myres);
            setLoading4(loading4 + 1);
            handlechange();
            return myres;
          })
          .catch(error => {
            console.error(error);
          });
      }
    handlechange();
        
  };

  const [isreserved, setIsReserved] = useState(false);

  const onmyReserve = () => {
    setLoading3((loading3)=>{return loading3+1});
     myReserve();
    setTimeout(() => {
      if (myres.length > 0) {
        setIsReserved(true);
      } else {
        setIsReserved(false);
      }
         }, 2000);
  }; 

  const [visible, setVisible] = useState(false); 

  return (
    <SafeAreaView style={{flex: 1, backgroundColor: 'white'}}>
      <Modal transparent={true} visible={visible} animationType="slide">
        <View style={styles.modalContainer}>
          <View style={styles.modalContent}>
            {loading3!=loading4?(<View style={{flex: 7, justifyContent: 'center', alignItems: 'center'}}>
          <View style={{flex: 1}} />
          <Text>현재 예약가능한 기구가 없습니다.</Text>
          <View style={{flex: 5}} />
        </View>):(<ModalView
              isreserved={isreserved}
              usermachine={usermachine}
              handlerFunction={handlechange}
              change1={change1}></ModalView>)}
            
            <Button
              title={'확인'}
              onPress={() => {
                setVisible('false');
              }}></Button>
          </View>
        </View>
      </Modal>
      <View style={styles.btn1view}>
        <Button
          title="나의 예약내역 조회/수정"
          color={'#26a96a'}
          onPress={() => {
            onmyReserve();
            setVisible(true);
          }}
        />
      </View>
      <View style={styles.seperator}></View>
      {loading != loading2 ? (
        <View style={{flex: 7, justifyContent: 'center', alignItems: 'center'}}>
          <View style={{flex: 1}} />
          <Text>현재 예약가능한 기구가 없습니다.</Text>
          <View style={{flex: 5}} />
        </View>
      ) : (
        <MachineView
          machine={machines}
          handlerFunction={handlechange}
          change1={change1}></MachineView>
      )}
      <View style={{height: '5%'}}></View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  seperator: {
    height: 1,
    backgroundColor: 'black',
    marginVertical: 10,
  },
  btn1view: {
    flex: 0.6,
    backgroundColor: 'white',
    flexDirection: 'row-reverse',
    alignItems: 'center',
  },
  categoryView: {
    flex: 0.5,
    backgroundColor: 'white',
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
  sortView: {flex: 0.5, flexDirection: 'row', marginLeft: 10},
  scrollView: {flex: 6, backgroundColor: 'white'},
  modalContainer: {
    flex: 1,
    padding: 20,
    justifyContent: 'center',
  },
  modalContent: {
    flex: 0.5,
    backgroundColor: 'white',
    alignItems: 'center',
    justifyContent: 'center',
    borderColor: 'black',
    borderWidth: 4,
    borderRadius: 20,
  },
});

export default ReserveScreen;

模态视图.js

import React from 'react';
import {View, Text, Button, StyleSheet} from 'react-native';
import MachineModal from './MachineModal.js';
import Icon from 'react-native-vector-icons/MaterialIcons';
const ModalView = ({isreserved, usermachine, change1, handlerFunction}) => {
  const change2 = change1;
  function handleChange() {
    handlerFunction();
    console.log('handlechange()');
  }
  
  {
      return (
        <View>
          <Text>나의 예약내역</Text>
          {usermachine.map(item => {
            return (
              <View key={item.id}>
                <MachineModal
                  name={item.name}
                  id={item.id}
                  waitnum={item.waitnum}
                  change2={change2}
                  handlerFunction={handleChange}></MachineModal>
              </View>
            );
          })}
        </View>
      );
    
  }
};

const styles = StyleSheet.create({});
export default ModalView;

MachineModal.js

import React, {useState} from 'react';
import {View, Text, Button, Alert, StyleSheet, Image} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage'; 


const MachineModal = ({name, id, waitnum, change2, handlerFunction}) => {
  const formatted = `기구명 : ${name}\n\n현재 대기인원 : ${waitnum}명`;
  const [userid, setUserid] = useState('');
  const getusername = async () => {
    try {
      const uid = await AsyncStorage.getItem('@storage_userid');
      setUserid(uid);
      return;
    } catch (e) {
      console.log(e);
    }
  };
  getusername();

  const change3 = change2;
  function handlechange1() {
    handlerFunction();
  }

  const machinereturn = (machineid, usid) => {
    try {
      fetch(
        'https://so6wenvyg8.execute-api.ap-northeast-2.amazonaws.com/dev/return',
        {
          method: 'POST',
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            machineid: String(machineid),
            userid: String(usid),
          }),
        },
      )
        .then(response => response.json())
        .then(json => {
          console.log(json);
          try {
            tim = json['time'];
            handlechange1();
            Alert.alert('반납되었습니다.');
            return 1;
          } catch (e) {
            handlechange1();
            Alert.alert('반납에 실패했습니다.');
            return -1;
          }
        });
    } catch (e) {
      console.log('17');
      console.log(e);
    }
  };

  return (
    <View style={styles.machine}>
      <Image
        source={require('../images/default_image.png')}
        style={{width: 70, height: 70}}></Image>
      <Text>{formatted}</Text>
      <Button
        title="예약취소"
        onPress={() => machinereturn(id, userid)}></Button>
    </View>
  );
};

const styles = StyleSheet.create({
  machine: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    paddingTop: 7,
    paddingBottom: 7,
    borderBottomColor: 'black',
    borderBottomWidth: 1,
    alignItems: 'center',
  },
});
export default MachineModal;

您没有使用json setUserMachine 您将其设置为myres ,尚未更新为json["reservation"] 这是对 React 的一个很常见的误解。 State 更新直到您的组件 function 运行后才会发生。

此外,您应该将getusername类的内容放入效果中。 否则,将在每次渲染时调用getusername之类的函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM