子组件传递参数到父组件 (回调)
- 在父组件中定义一个带参数的方法
getProductPrice(price) {
this.setState({
price
});
}
price就是最后回调的参数。设置给state就会刷新父组件的视图。
- 在父组件中使用子组件 并设置参数
getProductPrice
<ProductItem getProductPrice={(price)=>this.getProductPrice(price)}></ProductItem>
参数price就是回调回来的参数。
- 在子组件中调用
componentDidMount() {
AsyncStorage.getAllKeys((err, keys) => {
console.log(keys);
if (err) {
alert(err);
}
AsyncStorage.multiGet(keys, (err, result) => {
console.log('result : ' + result);
let arr = [];
let price = 0;
for (let i in result) {
arr.push(JSON.parse(result[i][1]));
price += JSON.parse(result[i][1]).price;
}
this.setState({
arr,
price
});
this.props.getProductPrice(price);
});
});
}
getProductPrice回存在props属性中,把price传进入,最后就可以在父控件中拿到该参数。
父控件调用子组件的函数(ref属性)
1.父控件定义ref属性
<ProductItem getProductPrice={(price)=>this.getProductPrice(price)} ref={(ProductItem)=>{this.refProductItem = ProductItem}}></ProductItem>
ref属性指定的就是ProductItem组件。
2.在子组件中定义函数
clear() {
this.setState({
arr: [],
price: 0,
});
}
在子组件中定义了一个清除的方法。这个可以随便定义的。
- 最后在父组件中使用ref属性调用子组件中定义的方法
this.refProductItem.clear();
这样就会调用子组件中的函数了。
navigation传递函数
事故现场:有3个界面ABC,A页面开启B,B界面开启C,现在 C的逻辑处理完毕,需要传递B参数,并刷新视图。
- B在开启C页面传递一个函数
<TouchableOpacity onPress={()=>this.props.navigation.navigate('SettlementUi',{fetchData:()=>{this.setState({count:0})}})}>
<Text style={styles.btn}>去结算{str}</Text>
</TouchableOpacity>
B页面开启C页面并传递一个函数,函数的内容是重置count
,然后刷新视图。
- 在C界面拿到fetchData函数并调用。
clearProduct = () => {
AsyncStorage.clear();
this.setState({
price: 0,
arr: [],
});
this.refProductItem.clear();
// this.props.fetchData();
const {
goBack,
state
} = this.props.navigation
state.params.fetchData();
// goBack();
}
在C界面的this.props.navigation
拿到state,传递的参数就放在state.params中,取到函数就可以直接调用了。我这里还去了goBack函数。回退页面并刷新视图。
代码
HomeUi.js
import React, {
Component
} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
Image,
AsyncStorage,
TouchableHighlight,
} from 'react-native';
import {
createStackNavigator
} from 'react-navigation';
import SettlementUi from './SettlementUi';
const datas = [{
id: 1,
title: '泥猴桃1',
desc: '12个装',
price: 99,
url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
id: 2,
title: '泥猴桃2',
desc: '12个装',
price: 299,
url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
id: 3,
title: '泥猴桃3',
desc: '12个装',
price: 399,
url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
id: 4,
title: '泥猴桃4',
desc: '12个装',
price: 499,
url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
id: 5,
title: '泥猴桃5',
desc: '12个装',
price: 599,
url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
id: 6,
title: '泥猴桃6',
desc: '12个装',
price: 699,
url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}];
export default class HomeUI extends Component {
//<Image style={{flex:1,borderWidth: 1, borderColor: '#f00'}} source={{uri:'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'}} ></Image>
render() {
return (
<List navigation={this.props.navigation}></List>
);
}
}
class Item extends Component {
static defaultProps = {
title: 'https://gss0.bdstatic.com/5eR1dDebRNRTm2_p8IuM_a/res/img/richanglogo168_24.png',
url: '默认的标题',
};
static propTypes = {
title: React.PropTypes.string.isRequired,
url: React.PropTypes.string.isRequired,
};
/**
{
url:xxx,
text:xxx,
press:xxx,
}
*/
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.item_root}>
<TouchableOpacity style={styles.container} onPress={this.props.press}>
<Image resizeMode='contain' style={styles.images} source={{uri:this.props.url}}>
<Text numberOfLines={1} style={styles.desc} > {this.props.title}</Text>
</Image>
</TouchableOpacity>
</View>
);
}
}
class List extends Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
clear() {
this.setState({
count: 0,
});
}
press = (data) => {
this.setState({
count: this.state.count + 1
});
AsyncStorage.setItem('SP-' + this.genId() + '-SP', JSON.stringify(data), function(err) {
if (err) {
alert(err);
} else {
console.log('成功' + JSON.stringify(data));
}
});
}
//生成随机ID:GUID 全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符
//GUID生成的代码来自于Stoyan Stefanov
genId() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
let r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}).toUpperCase();
}
componentDidMount() {
let _that = this;
AsyncStorage.getAllKeys((err, keys) => {
console.log(keys);
if (err) {
console.log(err);
} else {
console.log('读取成功了的个数:' + keys.toString());
}
_that.setState({
count: keys.length
}, () => {
console.log(_that.state.count);
});
});
}
render() {
let list = [];
for (let i in datas) {
if (i % 2 === 0) {
list.push(
<View style={styles.item} key={i}>
<Item url={datas[i].url} title={datas[i].title} press={this.press.bind(this,datas[i])}></Item>
<Item url={datas[parseInt(i)+1].url} title={datas[parseInt(i)+1].title} press={()=>this.press(datas[parseInt(i)+1])}></Item>
</View>
);
}
}
let count = this.state.count;
let str = null;
if (count) {
str = ',共' + count + '件商品!';
}
return (
<View>
{list}
<TouchableOpacity onPress={()=>this.props.navigation.navigate('SettlementUi',{fetchData:()=>{this.setState({count:0})}})}>
<Text style={styles.btn}>去结算{str}</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
btn: {
marginTop: 10,
textAlignVertical: 'center',
height: 30,
textAlign: 'center',
marginRight: 5,
marginLeft: 5,
borderRadius: 5,
backgroundColor: '#FF7200',
color: '#fff',
fontSize: 18,
},
item_root: {
flex: 1,
height: 100,
},
item: {
flexDirection: 'row',
marginBottom: 10,
},
images: {
flex: 1,
borderWidth: 1,
margin: 5,
backgroundColor: 'transparent',
borderRadius: 5,
flexDirection: 'column-reverse',
},
desc: {
backgroundColor: "#0008",
height: 25,
color: '#fff',
textAlign: 'center',
lineHeight: 20,
textAlignVertical: 'center',
opacity: 0.7,
},
});
SettlementUi.js
import React, {
Component
} from 'react';
import {
View,
StyleSheet,
Text,
AsyncStorage,
TouchableOpacity,
ScrollView,
} from 'react-native';
const styles = StyleSheet.create({
btn: {
marginTop: 10,
textAlignVertical: 'center',
height: 30,
textAlign: 'center',
marginRight: 5,
marginLeft: 5,
borderRadius: 5,
backgroundColor: '#FF7200',
color: '#fff',
fontSize: 18,
},
container: {
flexDirection: 'row',
margin: 5,
borderRadius: 5,
borderWidth: 1,
borderColor: '#dddddd',
justifyContent: 'space-between',
},
text: {
marginLeft: 10,
marginRight: 10,
}
});
class ProductItem extends Component {
constructor(props) {
super(props);
this.state = {
arr: [],
price: 0,
}
}
clear() {
this.setState({
arr: [],
price: 0,
});
}
componentDidMount() {
AsyncStorage.getAllKeys((err, keys) => {
console.log(keys);
if (err) {
alert(err);
}
AsyncStorage.multiGet(keys, (err, result) => {
console.log('result : ' + result);
let arr = [];
let price = 0;
for (let i in result) {
arr.push(JSON.parse(result[i][1]));
price += JSON.parse(result[i][1]).price;
}
this.setState({
arr,
price
});
this.props.getProductPrice(price);
});
});
}
render() {
let datas = this.state.arr;
let list = [];
for (let i in datas) {
console.log(datas);
let str = datas[i].title + '号产品,' + datas[i].desc;
list.push(
<View style={styles.container} key={i}>
<Text style={styles.text}>{str}</Text>
<Text style={styles.text}>{datas[i].price}</Text>
</View>
);
}
return (
<View>
{list}
</View>
);
}
}
export default class SettlementUi extends Component {
constructor(props) {
super(props);
this.state = {
price: 0,
}
}
getProductPrice(price) {
this.setState({
price
});
}
clearProduct = () => {
AsyncStorage.clear();
this.setState({
price: 0,
arr: [],
});
this.refProductItem.clear();
// this.props.fetchData();
const {
goBack,
state
} = this.props.navigation
state.params.fetchData();
// goBack();
}
render() {
return (
<ScrollView>
<ProductItem getProductPrice={(price)=>this.getProductPrice(price)} ref={(ProductItem)=>{this.refProductItem = ProductItem}}></ProductItem>
<TouchableOpacity>
<Text style={styles.btn}>共支付,{this.state.price}</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>this.clearProduct()}>
<Text style={styles.btn}>清空购物车</Text>
</TouchableOpacity>
</ScrollView>
);
}
}
网友评论