Created
April 29, 2016 04:07
-
-
Save octaviogb/6d6baeeaa3e0d7cdc9326072bb8b912b to your computer and use it in GitHub Desktop.
IOS React Native exemplo comentado
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { | |
AppRegistry, // Registrador de aplicativo | |
StyleSheet, // Gerador de folha de estilos | |
Text, // Enclosure de textos | |
TextInput, // Input de textos | |
Image, // Objeto de imagem | |
TouchableHighlight, // Objeto clicável | |
View, // Caixa genérica, tipo div | |
Component, // Componente do React Native | |
PropTypes // Propriedades | |
} from 'react-native'; | |
function getData(username){ | |
// Utiliza o fetch api (https://developer.mozilla.org/en/docs/Web/API/Fetch_API) | |
// para fazer a consulta na API aberta do github | |
return fetch(`https://api.github.com/users/${username}`) | |
.then((d) => d.json()); // Pega a resposta e converte para json | |
} | |
class Input extends Component { | |
// Definição das propriedades dos componentes | |
// isso é importante pois serve tanto como validação | |
// quanto inicialização com valor vazio | |
static propTypes = { | |
onChange: PropTypes.func, | |
value: PropTypes.string, | |
label: PropTypes.string.isRequired // vê? é requerido... | |
}; | |
render() { | |
const {onChange, onSubmit, value, label} = this.props; // Gosto de fazer essa separação para não ter que escrever | |
// muita 'dot notation' no JSX | |
return (<View style={{position: 'relative'}}> | |
<Text>{label}</Text> | |
<TextInput onSubmitEditing={onSubmit} onSubmitBlur={true} style={styles.input} onChangeText={(ev) => onChange && onChange(ev)} value={value||''}/> | |
<View style={styles.hr}/> | |
</View>); | |
} | |
} | |
// A melhor prática seria colocar cada componente | |
// em um arquivo separado, na pasta de componentes | |
class Button extends Component { | |
static propTypes = { | |
label: PropTypes.string.isRequired, | |
onPress: PropTypes.func | |
}; | |
render() { | |
const {label, onPress} = this.props; | |
return (<TouchableHighlight onPress={(ev)=> onPress && onPress(ev)} style={styles.button}> | |
<View > | |
<Text style={styles.buttonText}> | |
{label} | |
</Text> | |
</View> | |
</TouchableHighlight>); | |
} | |
} | |
class Card extends Component { | |
static propTypes: { | |
data: PropTypes.object | |
}; | |
render() { | |
const {name, location, email, avatar_url} = this.props.data; | |
return (<View style={styles.card}> | |
<Image | |
style={styles.avatar} | |
source={{uri: avatar_url}} | |
/> | |
<Text>Nome:</Text> | |
<Text>{name}</Text> | |
<Text>Localiação:</Text> | |
<Text>{location}</Text> | |
<Text>Email:</Text> | |
<Text>{email}</Text> | |
</View>); | |
} | |
} | |
// Esse seria o componente importado | |
// toranando a aplicação genérica | |
class SampleApp extends Component{ | |
constructor(props) { | |
super(props); // Compece sempre com o 'super(props)' | |
this.state = { | |
isFetching: false, // Isso é bacana para colocar um spinner | |
error: null, // Como não temos muito tempo, não tratarei erros | |
data: null, // Aqui serão definidos os valores do retorno da API | |
username: null, // Este é o nome de usuário que será consultado | |
} | |
} | |
onChange(text) { | |
console.log('change', text); | |
this.setState({ | |
...this.state, | |
username: text.toLowerCase() | |
}); | |
} | |
send() { | |
if(!this.state.username) { | |
alert('Nome de usuário inválido'); // É possível lançar um alerta como no browser | |
return false; | |
} | |
console.log('send'); | |
this.setState({ | |
...this.state, | |
isFetching: true, | |
error: null, | |
}); | |
getData(this.state.username) | |
.then((d) => this.setState({ | |
...this.state, | |
data: d, | |
isFetching: false | |
}, () => console.log('success', this.state.data))) | |
.catch((err) => this.setState({ | |
...this.state, | |
error: err, | |
isFetching: false | |
}, () => console.log('error', this.state.error))) | |
} | |
render() { | |
return (<View style={styles.container}> | |
<Input label="Usuário" onSubmit={this.send.bind(this)} onChange={this.onChange.bind(this)} value={this.state.username}/> | |
<Button label="Buscar" onPress={this.send.bind(this)}/> | |
{this.state.data && <Card data={this.state.data}/>} | |
</View>); | |
} | |
} | |
// A folha de estilos do react-native parece CSS, mas não é! | |
var styles = StyleSheet.create({ | |
container: { | |
flex: 1, // Todo o layout do react-native é em flexbox | |
justifyContent: 'space-between', | |
padding: 5, // Não é necessário colocar 'px' | |
paddingTop: 20, | |
backgroundColor: '#F5FCFF' // Não há shorthands, muitas propriedades acabam um pouco diferentes do CSS | |
}, | |
input: { | |
flex: 1, // Esta é a proporção que o objeto irá tomar no container | |
height: 40 | |
}, | |
hr: { | |
position: 'absolute', | |
left:0, | |
right:0, | |
backgroundColor: 'gray', | |
height:1, | |
bottom:0, | |
flex: 1 | |
}, | |
button: { | |
alignSelf: 'center', | |
margin: 5, | |
height: 40, | |
width: 200, | |
padding: 10, | |
backgroundColor: 'purple', | |
borderRadius: 5, | |
shadowColor: 'gray', // as shadows só funcionam no iOS | |
shadowOffset: {width: 1, height: 1}, // no Android você usa elevation | |
shadowRadius: 2, | |
shadowOpacity: .5 | |
}, | |
buttonText: { | |
textAlign: 'center', // Alinhamento e estilos de texto só podem ser aplicados em <Text/> | |
color: 'white' | |
}, | |
card: { | |
flex: 2, // Este objeto poderá ser o dobro dos outros | |
backgroundColor: '#fefefe', | |
margin: 10, | |
padding: 5, | |
shadowColor: 'gray', | |
shadowOffset: {width: 3, height: 3}, | |
shadowRadius: 5, | |
shadowOpacity: .5 | |
}, | |
avatar: { | |
width: 120, | |
height: 120, | |
borderRadius: 60, // para arredondar 100%, use metade do width e height aqui | |
alignSelf: 'center', | |
borderWidth: 1, | |
margin: 15 | |
} | |
}); | |
AppRegistry.registerComponent('SampleApp', () => SampleApp); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment