I have this video, playing in zindex: -1 with a button and a text input floating over it. The issue is when the text changes, it's supposed to manipulate that state object, not fire the touchable highlight's on click function.
When I use the suggestion given yesterday, the error turns into a warning. If I type 7 random letters in the input box, I'll get 7 warnings saying: "warning bind() you are binding a ponent method to the ponent", which means the input box is continuing to call the touchable highlight's function.
I'm using this library for React Native to use it's streaming capabilities: . It's pretty nice!
On one of it's examples, .js there are these lines of code I'm fiddling with:
_renderTextRoom() {
return (
<View style={styles.listViewContainer}>
<ListView
dataSource={this.ds.cloneWithRows(this.state.textRoomData)}
enableEmptySections={true}
renderRow={rowData =>
<Text
style={styles.whiteOut}
>{`${rowData.user}: ${rowData.message}`}</Text>}
/>
<TextInput
style={[styles.whiteOut, styles.bgWhite]}
onChangeText={value => this.setState({ textRoomValue: value })}
value={this.state.textRoomValue}
/>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._textRoomPress()}>
<Text style={styles.bgWhite}>Send</Text>
</TouchableHighlight>
</View>
</View>
);
},
When I enter text into the text field, the this._textRoomPress() function nested within the TouchableHighlight is firing. What!? When I ment it out, it doesn't fire.
'use strict';
import React, { Component } from 'react';
import {
Dimensions,
StyleSheet,
Text,
TouchableHighlight,
View,
TextInput,
ListView,
ScrollView
} from 'react-native';
import { userData } from '../utils/Factory';
import io from 'socket.io-client';
var socket_one = '';
const socket = io.connect(socket_one, { transports: ['websocket'] });
import {
RTCPeerConnection,
RTCMediaStream,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStreamTrack,
getUserMedia,
} from 'react-native-webrtc';
const configuration = { "iceServers": [{ "url": "stun:stun.l.google:19302" }] };
const pcPeers = {};
let localStream;
var width = Dimensions.get('window').width; //full width
var height = Dimensions.get('window').height; //full height
function getLocalStream(isFront, callback) {
MediaStreamTrack.getSources(sourceInfos => {
console.log(sourceInfos);
let videoSourceId;
for (const i = 0; i < sourceInfos.length; i++) {
const sourceInfo = sourceInfos[i];
if (sourceInfo.kind == "video" && sourceInfo.facing == (isFront ? "front" : "back")) {
videoSourceId = sourceInfo.id;
}
}
getUserMedia({
audio: true,
video: {
mandatory: {
minWidth: 700, // Provide your own width, height and frame rate here
minHeight: 700,
minFrameRate: 30
},
facingMode: (isFront ? "user" : "environment"),
optional: [{ sourceId: sourceInfos.id }]
}
}, function(stream) {
console.log('dddd', stream);
callback(stream);
}, logError);
});
}
function join(roomID) {
socket.emit('join', roomID, function(socketIds) {
console.log('join', socketIds);
for (const i in socketIds) {
const socketId = socketIds[i];
createPC(socketId, true);
}
});
}
function createPC(socketId, isOffer) {
const pc = new RTCPeerConnection(configuration);
pcPeers[socketId] = pc;
pc.onicecandidate = function(event) {
// console.warn('onicecandidate', event.candidate);
if (event.candidate) {
socket.emit('exchange', { 'to': socketId, 'candidate': event.candidate });
}
};
function createOffer() {
pc.createOffer(function(desc) {
console.log('createOffer', desc);
pc.setLocalDescription(desc, function() {
console.log('setLocalDescription', pc.localDescription);
socket.emit('exchange', { 'to': socketId, 'sdp': pc.localDescription });
}, logError);
}, logError);
}
pc.onnegotiationneeded = function() {
console.log('onnegotiationneeded');
if (isOffer) {
createOffer();
}
}
pc.oniceconnectionstatechange = function(event) {
console.log('oniceconnectionstatechange', event.target.iceConnectionState);
if (event.target.iceConnectionState === 'pleted') {
setTimeout(() => {
getStats();
}, 1000);
}
if (event.target.iceConnectionState === 'connected') {
createDataChannel();
}
};
pc.onsignalingstatechange = function(event) {
console.log('onsignalingstatechange', event.target.signalingState);
};
pc.onaddstream = function(event) {
console.log('onaddstream', event.stream);
// container.setState({ info: 'One peer join!' });
container.setState({ info: 'Connected!' });
const remoteList = container.state.remoteList;
remoteList[socketId] = event.stream.toURL();
container.setState({ remoteList: remoteList });
};
pc.onremovestream = function(event) {
console.log('onremovestream', event.stream);
};
pc.addStream(localStream);
function createDataChannel() {
if (pc.textDataChannel) {
return;
}
const dataChannel = pc.createDataChannel("text");
dataChannel.onerror = function(error) {
console.log("dataChannel.onerror", error);
};
dataChannel.onmessage = function(event) {
console.log("dataChannel.onmessage:", event.data);
container.receiveTextData({ user: socketId, message: event.data });
};
dataChannel.onopen = function() {
console.log('dataChannel.onopen');
container.setState({ textRoomConnected: true });
};
dataChannel.onclose = function() {
console.log("dataChannel.onclose");
};
pc.textDataChannel = dataChannel;
}
return pc;
}
function exchange(data) {
const fromId = data.from;
let pc;
if (fromId in pcPeers) {
pc = pcPeers[fromId];
} else {
pc = createPC(fromId, false);
}
if (data.sdp) {
console.log('exchange sdp', data);
pc.setRemoteDescription(new RTCSessionDescription(data.sdp), function() {
if (pc.remoteDescription.type == "offer")
pc.createAnswer(function(desc) {
console.log('createAnswer', desc);
pc.setLocalDescription(desc, function() {
console.log('setLocalDescription', pc.localDescription);
socket.emit('exchange', { 'to': fromId, 'sdp': pc.localDescription });
}, logError);
}, logError);
}, logError);
} else {
console.log('exchange candidate', data);
pc.addIceCandidate(new RTCIceCandidate(data.candidate));
}
}
function leave(socketId) {
console.log('leave', socketId);
const pc = pcPeers[socketId];
const viewIndex = pc.viewIndex;
pc.close();
delete pcPeers[socketId];
const remoteList = container.state.remoteList;
delete remoteList[socketId]
container.setState({ remoteList: remoteList });
container.setState({ info: 'One peer leave!' });
}
socket.on('exchange', function(data) {
exchange(data);
});
socket.on('leave', function(socketId) {
leave(socketId);
});
socket.on('connect', function(data) {
console.log('connected');
});
function initStream() {
getLocalStream(true, function(stream) {
localStream = stream;
container.setState({ selfViewSrc: stream.toURL() });
// container.setState({ status: 'ready', info: 'Please enter or create room ID' });
container.setState({ status: 'connect', info: 'Connecting' });
if (userData.inDanger) {
join(0);
} else {
join(userData.userName);
// join(userData.nowPlaying);
}
});
}
function logError(error) {
console.log("logError", error);
}
function mapHash(hash, func) {
const array = [];
for (const key in hash) {
const obj = hash[key];
array.push(func(obj, key));
}
return array;
}
function _textRoomPress() {
if (!container.textRoomValue) {
return
}
const textRoomData = container.textRoomData.slice();
textRoomData.push({ user: 'Me', message: container.textRoomValue });
for (const key in pcPeers) {
const pc = pcPeers[key];
pc.textDataChannel.send(container.textRoomValue);
}
container.setState({ textRoomData, textRoomValue: '' });
}
function getStats() {
const pc = pcPeers[Object.keys(pcPeers)[0]];
if (pc.getRemoteStreams()[0] && pc.getRemoteStreams()[0].getAudioTracks()[0]) {
const track = pc.getRemoteStreams()[0].getAudioTracks()[0];
console.log('track', track);
pc.getStats(track, function(report) {
console.log('getStats report', report);
}, logError);
}
}
let container;
const Stream = React.createClass({
getInitialState: function() {
this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => true });
return {
info: 'Initializing',
status: 'init',
roomID: '',
// isFront: true,
isFront: false,
selfViewSrc: null,
remoteList: {},
textRoomConnected: false,
textRoomData: [],
textRoomValue: '',
};
},
ponentDidMount: function() {
container = this;
initStream();
},
_press(event) {
// this.refs.roomID.blur();
this.setState({ status: 'connect', info: 'Connecting' });
join(userData.userName);
// join(this.state.roomID);
},
_switchVideoType() {
const isFront = !this.state.isFront;
this.setState({ isFront });
getLocalStream(isFront, function(stream) {
if (localStream) {
for (const id in pcPeers) {
const pc = pcPeers[id];
pc && pc.removeStream(localStream);
}
localStream.release();
}
localStream = stream;
container.setState({ selfViewSrc: stream.toURL() });
for (const id in pcPeers) {
const pc = pcPeers[id];
pc && pc.addStream(localStream);
}
});
},
receiveTextData(data) {
const textRoomData = this.state.textRoomData.slice();
textRoomData.push(data);
this.setState({ textRoomData, textRoomValue: '' });
},
_textRoomPress() {
if (!this.state.textRoomValue) {
return
}
const textRoomData = this.state.textRoomData.slice();
textRoomData.push({ user: 'Me', message: this.state.textRoomValue });
for (const key in pcPeers) {
const pc = pcPeers[key];
pc.textDataChannel.send(this.state.textRoomValue);
}
this.setState({ textRoomData, textRoomValue: '' });
},
_renderTextRoom() {
return (
<View style={styles.listViewContainer}>
<ListView
dataSource={this.ds.cloneWithRows(this.state.textRoomData)}
enableEmptySections={true}
renderRow={rowData =>
<Text
style={styles.whiteOut}
>{`${rowData.user}: ${rowData.message}`}</Text>}
/>
<TextInput
style={[styles.whiteOut, styles.bgWhite]}
onChangeText={value => this.setState({ textRoomValue: value })}
value={this.state.textRoomValue}
/>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._textRoomPress()}>
<Text style={styles.bgWhite}>Send</Text>
</TouchableHighlight>
</View>
</View>
);
},
render() {
return (
<View style={styles.container}>
{
mapHash(this.state.remoteList, (remote, index) => {
return (
<ScrollView key={index}>
<RTCView key={index} streamURL={this.state.selfViewSrc} style={styles.remoteView}>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._switchVideoType}>
<Text>Switch camera</Text>
</TouchableHighlight>
</View>
<View style={styles.bottomContainer}>
{this.state.textRoomConnected && this._renderTextRoom()}
</View>
</RTCView>
)
})
}
</View>
);
}
});
const styles = StyleSheet.create({
container: {
flex: 10,
// justifyContent: 'center',
backgroundColor: 'rgba(0,0,0, .0)',
},
topContainer: {
flex: 10,
backgroundColor: '#c7c7c7',
},
bottomContainer: {
flex: 1,
justifyContent: 'flex-end',
// backgroundColor: '#ffeeff',
'zIndex': 1,
backgroundColor: 'rgba(0,0,0, .0)',
},
selfView: {
width: 0,
height: 0
},
remoteView: {
flex: 1,
'zIndex': -1,
// backgroundColor: '#c7c7c7',
backgroundColor: '#f0f0f0',
width: width,
height: height - 25,
resizeMode: 'stretch', // or 'stretch'
},
wele: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
listViewContainer: {
height: 150,
},
buttonContainer: {
height: 50,
// backgroundColor: 'powderblue',
justifyContent: 'center',
alignItems: 'center',
},
button: {
marginTop: 50,
marginBottom: 50,
padding: 10,
paddingLeft: 30,
paddingRight: 30,
borderWidth: 1,
borderColor: 'rgba(0, 0, 0, .75)',
},
whiteOut: {
// color: "#ffffff",
color: "#000",
},
bgWhite: {
// backgroundColor: "#ffffff"
},
listView: {
// backgroundColor: "#ffffff",
flex: 10,
// flexDirection: 'row',
// justifyContent: 'center',
// alignItems: 'center',
}
});
export default Stream;
I have this video, playing in zindex: -1 with a button and a text input floating over it. The issue is when the text changes, it's supposed to manipulate that state object, not fire the touchable highlight's on click function.
When I use the suggestion given yesterday, the error turns into a warning. If I type 7 random letters in the input box, I'll get 7 warnings saying: "warning bind() you are binding a ponent method to the ponent", which means the input box is continuing to call the touchable highlight's function.
I'm using this library for React Native to use it's streaming capabilities: https://github./oney/react-native-webrtc. It's pretty nice!
On one of it's examples, https://github./oney/RCTWebRTCDemo/blob/master/main.js there are these lines of code I'm fiddling with:
_renderTextRoom() {
return (
<View style={styles.listViewContainer}>
<ListView
dataSource={this.ds.cloneWithRows(this.state.textRoomData)}
enableEmptySections={true}
renderRow={rowData =>
<Text
style={styles.whiteOut}
>{`${rowData.user}: ${rowData.message}`}</Text>}
/>
<TextInput
style={[styles.whiteOut, styles.bgWhite]}
onChangeText={value => this.setState({ textRoomValue: value })}
value={this.state.textRoomValue}
/>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._textRoomPress()}>
<Text style={styles.bgWhite}>Send</Text>
</TouchableHighlight>
</View>
</View>
);
},
When I enter text into the text field, the this._textRoomPress() function nested within the TouchableHighlight is firing. What!? When I ment it out, it doesn't fire.
'use strict';
import React, { Component } from 'react';
import {
Dimensions,
StyleSheet,
Text,
TouchableHighlight,
View,
TextInput,
ListView,
ScrollView
} from 'react-native';
import { userData } from '../utils/Factory';
import io from 'socket.io-client';
var socket_one = 'https://xxxxxxxxxxxxxx.herokuapp.';
const socket = io.connect(socket_one, { transports: ['websocket'] });
import {
RTCPeerConnection,
RTCMediaStream,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStreamTrack,
getUserMedia,
} from 'react-native-webrtc';
const configuration = { "iceServers": [{ "url": "stun:stun.l.google.:19302" }] };
const pcPeers = {};
let localStream;
var width = Dimensions.get('window').width; //full width
var height = Dimensions.get('window').height; //full height
function getLocalStream(isFront, callback) {
MediaStreamTrack.getSources(sourceInfos => {
console.log(sourceInfos);
let videoSourceId;
for (const i = 0; i < sourceInfos.length; i++) {
const sourceInfo = sourceInfos[i];
if (sourceInfo.kind == "video" && sourceInfo.facing == (isFront ? "front" : "back")) {
videoSourceId = sourceInfo.id;
}
}
getUserMedia({
audio: true,
video: {
mandatory: {
minWidth: 700, // Provide your own width, height and frame rate here
minHeight: 700,
minFrameRate: 30
},
facingMode: (isFront ? "user" : "environment"),
optional: [{ sourceId: sourceInfos.id }]
}
}, function(stream) {
console.log('dddd', stream);
callback(stream);
}, logError);
});
}
function join(roomID) {
socket.emit('join', roomID, function(socketIds) {
console.log('join', socketIds);
for (const i in socketIds) {
const socketId = socketIds[i];
createPC(socketId, true);
}
});
}
function createPC(socketId, isOffer) {
const pc = new RTCPeerConnection(configuration);
pcPeers[socketId] = pc;
pc.onicecandidate = function(event) {
// console.warn('onicecandidate', event.candidate);
if (event.candidate) {
socket.emit('exchange', { 'to': socketId, 'candidate': event.candidate });
}
};
function createOffer() {
pc.createOffer(function(desc) {
console.log('createOffer', desc);
pc.setLocalDescription(desc, function() {
console.log('setLocalDescription', pc.localDescription);
socket.emit('exchange', { 'to': socketId, 'sdp': pc.localDescription });
}, logError);
}, logError);
}
pc.onnegotiationneeded = function() {
console.log('onnegotiationneeded');
if (isOffer) {
createOffer();
}
}
pc.oniceconnectionstatechange = function(event) {
console.log('oniceconnectionstatechange', event.target.iceConnectionState);
if (event.target.iceConnectionState === 'pleted') {
setTimeout(() => {
getStats();
}, 1000);
}
if (event.target.iceConnectionState === 'connected') {
createDataChannel();
}
};
pc.onsignalingstatechange = function(event) {
console.log('onsignalingstatechange', event.target.signalingState);
};
pc.onaddstream = function(event) {
console.log('onaddstream', event.stream);
// container.setState({ info: 'One peer join!' });
container.setState({ info: 'Connected!' });
const remoteList = container.state.remoteList;
remoteList[socketId] = event.stream.toURL();
container.setState({ remoteList: remoteList });
};
pc.onremovestream = function(event) {
console.log('onremovestream', event.stream);
};
pc.addStream(localStream);
function createDataChannel() {
if (pc.textDataChannel) {
return;
}
const dataChannel = pc.createDataChannel("text");
dataChannel.onerror = function(error) {
console.log("dataChannel.onerror", error);
};
dataChannel.onmessage = function(event) {
console.log("dataChannel.onmessage:", event.data);
container.receiveTextData({ user: socketId, message: event.data });
};
dataChannel.onopen = function() {
console.log('dataChannel.onopen');
container.setState({ textRoomConnected: true });
};
dataChannel.onclose = function() {
console.log("dataChannel.onclose");
};
pc.textDataChannel = dataChannel;
}
return pc;
}
function exchange(data) {
const fromId = data.from;
let pc;
if (fromId in pcPeers) {
pc = pcPeers[fromId];
} else {
pc = createPC(fromId, false);
}
if (data.sdp) {
console.log('exchange sdp', data);
pc.setRemoteDescription(new RTCSessionDescription(data.sdp), function() {
if (pc.remoteDescription.type == "offer")
pc.createAnswer(function(desc) {
console.log('createAnswer', desc);
pc.setLocalDescription(desc, function() {
console.log('setLocalDescription', pc.localDescription);
socket.emit('exchange', { 'to': fromId, 'sdp': pc.localDescription });
}, logError);
}, logError);
}, logError);
} else {
console.log('exchange candidate', data);
pc.addIceCandidate(new RTCIceCandidate(data.candidate));
}
}
function leave(socketId) {
console.log('leave', socketId);
const pc = pcPeers[socketId];
const viewIndex = pc.viewIndex;
pc.close();
delete pcPeers[socketId];
const remoteList = container.state.remoteList;
delete remoteList[socketId]
container.setState({ remoteList: remoteList });
container.setState({ info: 'One peer leave!' });
}
socket.on('exchange', function(data) {
exchange(data);
});
socket.on('leave', function(socketId) {
leave(socketId);
});
socket.on('connect', function(data) {
console.log('connected');
});
function initStream() {
getLocalStream(true, function(stream) {
localStream = stream;
container.setState({ selfViewSrc: stream.toURL() });
// container.setState({ status: 'ready', info: 'Please enter or create room ID' });
container.setState({ status: 'connect', info: 'Connecting' });
if (userData.inDanger) {
join(0);
} else {
join(userData.userName);
// join(userData.nowPlaying);
}
});
}
function logError(error) {
console.log("logError", error);
}
function mapHash(hash, func) {
const array = [];
for (const key in hash) {
const obj = hash[key];
array.push(func(obj, key));
}
return array;
}
function _textRoomPress() {
if (!container.textRoomValue) {
return
}
const textRoomData = container.textRoomData.slice();
textRoomData.push({ user: 'Me', message: container.textRoomValue });
for (const key in pcPeers) {
const pc = pcPeers[key];
pc.textDataChannel.send(container.textRoomValue);
}
container.setState({ textRoomData, textRoomValue: '' });
}
function getStats() {
const pc = pcPeers[Object.keys(pcPeers)[0]];
if (pc.getRemoteStreams()[0] && pc.getRemoteStreams()[0].getAudioTracks()[0]) {
const track = pc.getRemoteStreams()[0].getAudioTracks()[0];
console.log('track', track);
pc.getStats(track, function(report) {
console.log('getStats report', report);
}, logError);
}
}
let container;
const Stream = React.createClass({
getInitialState: function() {
this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => true });
return {
info: 'Initializing',
status: 'init',
roomID: '',
// isFront: true,
isFront: false,
selfViewSrc: null,
remoteList: {},
textRoomConnected: false,
textRoomData: [],
textRoomValue: '',
};
},
ponentDidMount: function() {
container = this;
initStream();
},
_press(event) {
// this.refs.roomID.blur();
this.setState({ status: 'connect', info: 'Connecting' });
join(userData.userName);
// join(this.state.roomID);
},
_switchVideoType() {
const isFront = !this.state.isFront;
this.setState({ isFront });
getLocalStream(isFront, function(stream) {
if (localStream) {
for (const id in pcPeers) {
const pc = pcPeers[id];
pc && pc.removeStream(localStream);
}
localStream.release();
}
localStream = stream;
container.setState({ selfViewSrc: stream.toURL() });
for (const id in pcPeers) {
const pc = pcPeers[id];
pc && pc.addStream(localStream);
}
});
},
receiveTextData(data) {
const textRoomData = this.state.textRoomData.slice();
textRoomData.push(data);
this.setState({ textRoomData, textRoomValue: '' });
},
_textRoomPress() {
if (!this.state.textRoomValue) {
return
}
const textRoomData = this.state.textRoomData.slice();
textRoomData.push({ user: 'Me', message: this.state.textRoomValue });
for (const key in pcPeers) {
const pc = pcPeers[key];
pc.textDataChannel.send(this.state.textRoomValue);
}
this.setState({ textRoomData, textRoomValue: '' });
},
_renderTextRoom() {
return (
<View style={styles.listViewContainer}>
<ListView
dataSource={this.ds.cloneWithRows(this.state.textRoomData)}
enableEmptySections={true}
renderRow={rowData =>
<Text
style={styles.whiteOut}
>{`${rowData.user}: ${rowData.message}`}</Text>}
/>
<TextInput
style={[styles.whiteOut, styles.bgWhite]}
onChangeText={value => this.setState({ textRoomValue: value })}
value={this.state.textRoomValue}
/>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._textRoomPress()}>
<Text style={styles.bgWhite}>Send</Text>
</TouchableHighlight>
</View>
</View>
);
},
render() {
return (
<View style={styles.container}>
{
mapHash(this.state.remoteList, (remote, index) => {
return (
<ScrollView key={index}>
<RTCView key={index} streamURL={this.state.selfViewSrc} style={styles.remoteView}>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._switchVideoType}>
<Text>Switch camera</Text>
</TouchableHighlight>
</View>
<View style={styles.bottomContainer}>
{this.state.textRoomConnected && this._renderTextRoom()}
</View>
</RTCView>
)
})
}
</View>
);
}
});
const styles = StyleSheet.create({
container: {
flex: 10,
// justifyContent: 'center',
backgroundColor: 'rgba(0,0,0, .0)',
},
topContainer: {
flex: 10,
backgroundColor: '#c7c7c7',
},
bottomContainer: {
flex: 1,
justifyContent: 'flex-end',
// backgroundColor: '#ffeeff',
'zIndex': 1,
backgroundColor: 'rgba(0,0,0, .0)',
},
selfView: {
width: 0,
height: 0
},
remoteView: {
flex: 1,
'zIndex': -1,
// backgroundColor: '#c7c7c7',
backgroundColor: '#f0f0f0',
width: width,
height: height - 25,
resizeMode: 'stretch', // or 'stretch'
},
wele: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
listViewContainer: {
height: 150,
},
buttonContainer: {
height: 50,
// backgroundColor: 'powderblue',
justifyContent: 'center',
alignItems: 'center',
},
button: {
marginTop: 50,
marginBottom: 50,
padding: 10,
paddingLeft: 30,
paddingRight: 30,
borderWidth: 1,
borderColor: 'rgba(0, 0, 0, .75)',
},
whiteOut: {
// color: "#ffffff",
color: "#000",
},
bgWhite: {
// backgroundColor: "#ffffff"
},
listView: {
// backgroundColor: "#ffffff",
flex: 10,
// flexDirection: 'row',
// justifyContent: 'center',
// alignItems: 'center',
}
});
export default Stream;
Share
Improve this question
edited Dec 27, 2016 at 2:53
Dr. Div
asked Dec 12, 2016 at 17:47
Dr. DivDr. Div
97114 silver badges27 bronze badges
3 Answers
Reset to default 7Replace it with this._textRoomPress.bind(this)
It is not firing arbitrarily, it is firing every time a render is issued. That happens because whatever you pass to an object as a prop is evaluated before being passed (as the parameters of a function are, basically), and so what you are passing is the returning value of the function, which of course is not what you want. By passing this._textRoomPress
(with the optional bind
in case that you want to keep the context of the object), you pass a reference to the function that will be later called by the ponent on the appropriate time (when the element is pressed).
Since you're using createClass and not the es6 syntax, all the methods are already autobinding to the Component. Simply just change your onPress to:
onPress={this._textRoomPress}>
If you use onPress={this._textRoomPress()}>
It is instantly invoking that function anytime your ponent gets rendered.
In javascript you use <function name>()
to invoke a function... What you are doing here is simply invoking that function every time that _renderTextRoom()
gets called rather than assigning it to the onPress prop. What I would suggest is that you pass an anonymous function in as the prop (without calling it) which than returns the invocation of this._textRoomPress
. ES6 arrow functions make this super easy because they do not bind their own this
more info here
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={() => this._textRoomPress()}>
<Text style={styles.bgWhite}>Send</Text>
</TouchableHighlight>
</View>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744238039a4564566.html
评论列表(0条)