Reactjs React Native:如何从子组件上的事件重新引发父组件
我有两个部分 父组件:Reactjs React Native:如何从子组件上的事件重新引发父组件,reactjs,react-native,Reactjs,React Native,我有两个部分 父组件:App.js 子组件:Logitem.js 父组件呈现子组件的列表 每个子组件都有一个文本元素,单击该文本元素时,它会显示一个模态 模态有一个删除按钮,它执行删除操作 所有这些都很好 当我点击模态内部的delete按钮时,我设置了一个布尔变量来隐藏模态,它也可以工作 但是显示的列表(包含子组件的数组)不是最新的,即删除的元素仍然显示在列表中 是否有任何方法可以重新渲染父组件的render()方法 我已尝试通过子组件更新父组件(count)的状态,但仍然没有成功 我认为,如果
App.js
子组件:Logitem.js
父组件呈现子组件的列表
每个子组件都有一个文本元素,单击该文本元素时,它会显示一个模态
模态有一个删除按钮,它执行删除操作
所有这些都很好
当我点击模态内部的delete按钮时,我设置了一个布尔变量来隐藏模态,它也可以工作
但是显示的列表(包含子组件的数组)不是最新的,即删除的元素仍然显示在列表中
是否有任何方法可以重新渲染父组件的render()
方法
我已尝试通过子组件更新父组件(count
)的状态,但仍然没有成功
我认为,如果父组件的状态发生更改,将调用父组件的render(),但这不会发生
有人能告诉我这里能做些什么吗
父组件
import React, { Component } from 'react';
import { StyleSheet, View, Text, ScrollView, Modal, DatePickerIOS } from 'react-native';
import {
dropLogsTable,
createLogsTable,
getProfileHeightStandardfromDB,
saveLogsRecord,
populateDummyLogs,
getLogsRecords,
getLogsRecordsFromDB,
neverendingmethod,
getLogsDetailsforSaveDelete
} from '../src/helper';
import { Spinner } from '../src/Spinner';
import Logitem from '../src/Logitem';
export default class App extends Component {
state = {
allLogs:{
rows:{
_array:[{logstringdate:''}]
}
},
profileobject: {profileheight: 100, profilestandard: "XYZ"},
showspinner: true,
count:0
};
componentDidMount() {
this.fetchProfileData();
this.getAllLogs();
}
renderSpinner() {
if(this.state.showspinner) {
return <Spinner size="small" />;
}
else {
//return this.state.allLogs.rows._array.map(ae => <Text>{ae.bmi}</Text>);
return this.state.allLogs.rows._array.map(
(ae) => (
<View
key={ae.logdate}
>
<Logitem
logstringdate={ae.logstringdate}
bmi={ae.bmi}
weight={ae.metricweight}
logdate={ae.logdate}
incrementCount={() => this.setState({count: count+1)}
/>
</View>
)
);
}
}
async fetchProfileData() {
console.log('Before Profile Fetch');
const result = await getProfileHeightStandardfromDB();
console.log('After Profile Fetch');
console.log('Height : '+result.profileheight);
console.log('Standard: '+result.profilestandard);
this.setState({profileobject:result}); //Line Y
return result; //Line X
}
async getAllLogs() {
console.log('Before All Logs Fetch');
const allLogs = await getLogsRecordsFromDB();
console.log('After All Logs Fetch');
console.log('Spinner State ==>'+this.state.showspinner);
if(allLogs != null)
{
this.setState({allLogs, showspinner: false});
console.log('After async spinner state ==>'+this.state.showspinner);
console.log(allLogs);
}
return allLogs;
}
render() {
return (
<ScrollView style={styles.container}>
{this.renderSpinner()}
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
top: {
width: '100%',
flex: 1,
},
bottom: {
flex: 1,
alignItems: 'center',
},
});
import React, { Component } from 'react';
import { Text, View, Modal, DatePickerIOS, TextInput, Button } from 'react-native';
import {
deleteSelectedRecordDB
} from '../src/helper';
import { Spinner } from '../src/Spinner';
export default class Logitem extends Component {
constructor(props) {
super(props);
const { logstringdate, bmi, weight, logdate } = this.props;
}
state = {
selecteddate: '1',
selectedweight: this.props.weight,
showmodal: false,
date: new Date(86400000 * this.props.logdate),
}
async deleteSelectedRecord(){
console.log('Delete clicked');
console.log('this.state.selecteddate ==>' + this.state.selecteddate); //LINE X
const result = await deleteSelectedRecordDB(this.props.logdate);
console.log('deleteSelectedRecord after');
console.log('result ==> '+ result);
if (result)
{
this.setState({ showmodal: false });
this.props.incrementCount();
}
return result;
}
setModalVisible = (visible) => {
this.setState({showmodal: visible});
}
onWeightClick = () => {
this.setState({ selecteddate: this.props.logdate, showmodal: true }, () => {
console.log('Value in props==>' + this.props.logdate);
console.log('The selecteddate in the state ==> ' + this.state.selecteddate);
});
}
onDateChange(date) {
this.setState({
date: date
});
}
render() {
return (
<View style={styles.containerStyle}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.showmodal}
onRequestClose={() => {alert("Modal has been closed.")}}
>
<View style={{marginTop: 22}}>
<DatePickerIOS
date={this.state.date}
mode="date"
onDateChange={(date) => this.onDateChange(date)}
style={{ height: 100, width: 300 }}
/>
</View>
<View style={{ marginTop: 22, borderColor: '#ddd', borderWidth: 5 }}>
<TextInput
returnKeyType="done"
keyboardType='numeric'
style={{
height: 40,
width: 60,
borderColor: 'gray',
borderWidth: 1,
}}
onChangeText={(text) => this.setState({ selectedweight: text })}
value={this.state.selectedweight.toString()}
/>
<Text>KG</Text>
<Button
title="Delete"
onPress={this.deleteSelectedRecord.bind(this)}
style={{ marginTop: 200 }}
/>
</View>
</Modal>
<View style={styles.headerContentStyle}>
<Text>{this.props.logstringdate}</Text>
<Text>{this.props.bmi}</Text>
</View>
<View style={styles.thumbnailContainerStyle}>
<Text onPress={this.onWeightClick}>{this.props.weight}</Text>
</View>
</View>
);
}
};
const styles = {
containerStyle: {
borderWidth: 1,
borderRadius: 2,
borderColor: '#ddd',
borderBottomWidth: 0,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2},
shadowOpacity: 0.1,
shadowRadius: 2,
elevation: 1,
marginLeft: 5,
marginRight: 5,
marginTop:10,
},
thumbnailContainerStyle: {
justifyContent: 'center',
alignItems: 'center',
marginLeft: 10,
marginRight: 10,
flexDirection: 'row'
},
headerContentStyle: {
flexDirection: 'column',
justifyContent: 'space-around'
},
};
import React,{Component}来自'React';
从“react native”导入{样式表、视图、文本、滚动视图、模式、日期选择器};
进口{
水滴稳定,
createLogsTable,
getProfileHeightStandardfromDB,
保存日志记录,
人烟,
获取日志记录,
getLogsRecordsFromDB,
永远的方法,
getLogsDetailsforSaveDelete
}来自“../src/helper”;
从“../src/Spinner”导入{Spinner};
从“../src/Logitem”导入Logitem;
导出默认类应用程序扩展组件{
状态={
所有日志:{
行:{
_数组:[{logstringdate:''}]
}
},
profileobject:{profileheight:100,profilestandard:“XYZ”},
是的,
计数:0
};
componentDidMount(){
this.fetchProfileData();
这是一个.getAllLogs();
}
renderSpinner(){
if(this.state.showspinner){
返回;
}
否则{
//返回this.state.allLogs.rows.\u array.map(ae=>{ae.bmi});
返回此.state.allLogs.rows.\u array.map(
(ae)=>(
this.setState({count:count+1)}
/>
)
);
}
}
异步fetchProfileData(){
log('prefore Profile Fetch');
const result=等待getProfileHeightStandardfromDB();
log('After Profile Fetch');
console.log('Height:'+result.profileheight);
console.log('Standard:'+result.profilestandard);
this.setState({profileobject:result});//行Y
返回结果;//第X行
}
异步getAllLogs(){
console.log('在获取所有日志之前');
const allLogs=await getLogsRecordsFromDB();
log('After All Logs Fetch');
log('Spinner State==>'+this.State.showspinner);
如果(所有日志!=null)
{
this.setState({allLogs,showspinner:false});
console.log('After async spinner state==>'+this.state.showspinner);
console.log(所有日志);
}
返回所有日志;
}
render(){
返回(
{this.renderSpinner()}
);
}
}
const styles=StyleSheet.create({
容器:{
弹性:1,
},
顶部:{
宽度:“100%”,
弹性:1,
},
底部:{
弹性:1,
对齐项目:“居中”,
},
});
子组件
import React, { Component } from 'react';
import { StyleSheet, View, Text, ScrollView, Modal, DatePickerIOS } from 'react-native';
import {
dropLogsTable,
createLogsTable,
getProfileHeightStandardfromDB,
saveLogsRecord,
populateDummyLogs,
getLogsRecords,
getLogsRecordsFromDB,
neverendingmethod,
getLogsDetailsforSaveDelete
} from '../src/helper';
import { Spinner } from '../src/Spinner';
import Logitem from '../src/Logitem';
export default class App extends Component {
state = {
allLogs:{
rows:{
_array:[{logstringdate:''}]
}
},
profileobject: {profileheight: 100, profilestandard: "XYZ"},
showspinner: true,
count:0
};
componentDidMount() {
this.fetchProfileData();
this.getAllLogs();
}
renderSpinner() {
if(this.state.showspinner) {
return <Spinner size="small" />;
}
else {
//return this.state.allLogs.rows._array.map(ae => <Text>{ae.bmi}</Text>);
return this.state.allLogs.rows._array.map(
(ae) => (
<View
key={ae.logdate}
>
<Logitem
logstringdate={ae.logstringdate}
bmi={ae.bmi}
weight={ae.metricweight}
logdate={ae.logdate}
incrementCount={() => this.setState({count: count+1)}
/>
</View>
)
);
}
}
async fetchProfileData() {
console.log('Before Profile Fetch');
const result = await getProfileHeightStandardfromDB();
console.log('After Profile Fetch');
console.log('Height : '+result.profileheight);
console.log('Standard: '+result.profilestandard);
this.setState({profileobject:result}); //Line Y
return result; //Line X
}
async getAllLogs() {
console.log('Before All Logs Fetch');
const allLogs = await getLogsRecordsFromDB();
console.log('After All Logs Fetch');
console.log('Spinner State ==>'+this.state.showspinner);
if(allLogs != null)
{
this.setState({allLogs, showspinner: false});
console.log('After async spinner state ==>'+this.state.showspinner);
console.log(allLogs);
}
return allLogs;
}
render() {
return (
<ScrollView style={styles.container}>
{this.renderSpinner()}
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
top: {
width: '100%',
flex: 1,
},
bottom: {
flex: 1,
alignItems: 'center',
},
});
import React, { Component } from 'react';
import { Text, View, Modal, DatePickerIOS, TextInput, Button } from 'react-native';
import {
deleteSelectedRecordDB
} from '../src/helper';
import { Spinner } from '../src/Spinner';
export default class Logitem extends Component {
constructor(props) {
super(props);
const { logstringdate, bmi, weight, logdate } = this.props;
}
state = {
selecteddate: '1',
selectedweight: this.props.weight,
showmodal: false,
date: new Date(86400000 * this.props.logdate),
}
async deleteSelectedRecord(){
console.log('Delete clicked');
console.log('this.state.selecteddate ==>' + this.state.selecteddate); //LINE X
const result = await deleteSelectedRecordDB(this.props.logdate);
console.log('deleteSelectedRecord after');
console.log('result ==> '+ result);
if (result)
{
this.setState({ showmodal: false });
this.props.incrementCount();
}
return result;
}
setModalVisible = (visible) => {
this.setState({showmodal: visible});
}
onWeightClick = () => {
this.setState({ selecteddate: this.props.logdate, showmodal: true }, () => {
console.log('Value in props==>' + this.props.logdate);
console.log('The selecteddate in the state ==> ' + this.state.selecteddate);
});
}
onDateChange(date) {
this.setState({
date: date
});
}
render() {
return (
<View style={styles.containerStyle}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.showmodal}
onRequestClose={() => {alert("Modal has been closed.")}}
>
<View style={{marginTop: 22}}>
<DatePickerIOS
date={this.state.date}
mode="date"
onDateChange={(date) => this.onDateChange(date)}
style={{ height: 100, width: 300 }}
/>
</View>
<View style={{ marginTop: 22, borderColor: '#ddd', borderWidth: 5 }}>
<TextInput
returnKeyType="done"
keyboardType='numeric'
style={{
height: 40,
width: 60,
borderColor: 'gray',
borderWidth: 1,
}}
onChangeText={(text) => this.setState({ selectedweight: text })}
value={this.state.selectedweight.toString()}
/>
<Text>KG</Text>
<Button
title="Delete"
onPress={this.deleteSelectedRecord.bind(this)}
style={{ marginTop: 200 }}
/>
</View>
</Modal>
<View style={styles.headerContentStyle}>
<Text>{this.props.logstringdate}</Text>
<Text>{this.props.bmi}</Text>
</View>
<View style={styles.thumbnailContainerStyle}>
<Text onPress={this.onWeightClick}>{this.props.weight}</Text>
</View>
</View>
);
}
};
const styles = {
containerStyle: {
borderWidth: 1,
borderRadius: 2,
borderColor: '#ddd',
borderBottomWidth: 0,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2},
shadowOpacity: 0.1,
shadowRadius: 2,
elevation: 1,
marginLeft: 5,
marginRight: 5,
marginTop:10,
},
thumbnailContainerStyle: {
justifyContent: 'center',
alignItems: 'center',
marginLeft: 10,
marginRight: 10,
flexDirection: 'row'
},
headerContentStyle: {
flexDirection: 'column',
justifyContent: 'space-around'
},
};
import React,{Component}来自'React';
从“react native”导入{Text,View,Modal,datePickeros,TextInput,Button};
进口{
deleteSelectedRecordDB
}来自“../src/helper”;
从“../src/Spinner”导入{Spinner};
导出默认类Logitem扩展组件{
建造师(道具){
超级(道具);
const{logstringdate,bmi,weight,logdate}=this.props;
}
状态={
selecteddate:'1',
selectedweight:this.props.weight,
showmodal:错,
日期:新日期(86400000*this.props.logdate),
}
异步deleteSelectedRecord(){
log('Delete clicked');
console.log('this.state.selecteddate==>'+this.state.selecteddate);//第X行
const result=wait deleteSelectedRecordDB(this.props.logdate);
log('DeleteSelectedRecordAfter');
log('result==>'+result);
如果(结果)
{
this.setState({showmodel:false});
this.props.incrementCount();
}
返回结果;
}
setModalVisible=(可见)=>{
this.setState({showmodel:visible});
}
onWeightClick=()=>{
this.setState({selecteddate:this.props.logdate,showmodel:true},()=>{
log('props中的值==>'+this.props.logdate);
console.log('state==>'中的selecteddate+this.state.selecteddate);
});
}
onDateChange(日期){
这是我的国家({
日期:日期
});
}
render(){
返回(
{警报(“模式已关闭。”)}
>
此.onDateChange(日期)}
样式={{高度:100,宽度:300}
/>
this.setState({selectedweight:text})
值={this.state.selectedweight.toString()}
/>
公斤
{this.props.logstringdate}
{this.props.bmi}
{this.props.weight}
);
}
};
常量样式={
集装箱运输方式:{
边框宽度:1,
边界半径:2,
边框颜色:'#ddd',
边框底部宽度:0,
阴影颜色:“#000”,
阴影偏移:{宽度:0,高度:2},
阴影不透明度:0.1,
阴影半径:2,
立面图:1,
边缘左:5,
marginRight:5,
玛金托普:10,
},
thumbnailContainerStyle:{
为内容辩护:“中心”,
对齐项目:“居中”,
边缘左:10,
marginRight:10,
F