Caio Almeida
JSday @ Recife, 16 de Dezembro de 2017
ShoppingCartComponent
ShoppingCartComponent
CartListComponent
ShoppingCartComponent
CartListComponent
CartItemComponent
import React, { Component, PropTypes } from 'react';
class Embedly extends Component {
render() {
return (
<div className="embed">
<a id="embedly" href={this.props.url}></a>
</div>
);
}
}
export default Embedly;
Embedly.js
Imutáveis
Mutável
Relay: GraphQL Queries (leitura) e
Mutations (escrita (create, update, delete))
import React, { Component, PropTypes } from 'react';
class Example extends Component {
componentWillMount() {
window.alert('Your component is loading');
}
componentWillReceiveProps: function(nextProps) {
this.setState({
increasing: nextProps.count > this.props.count
});
}
componentDidMount() {
window.alert('Your component is ready');
}
render() {
return (<p>Mounted</p>)
}
}
export default Example;
class Tags extends Component {
render() {
return (
<ul className="tags-list">
{props.tags.map(function(tag) {
return (
<Tag tag={tag}>
);
})}
</ul>
);
}
}
Componente React
React.js
DOM
React Native
Android
iOS
https://github.com/meedan/generator-keefer
$ git clone 'https://github.com
/meedan/generator-keefer.git'
$ cd generator-keefer
$ cp config.yml.example config.yml
$ npm install -g yo
$ npm link
$ yo keefer
URL via parâmetro
$ PLATFORM=web npm run build
URL via link clicado ou endereço da aba atual
$ PLATFORM=chrome npm run build
URL via menu de compartilhamento
$ PLATFORM=android npm run build
React.JS x React Native
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
<View style={styles.container}>
</View>
https://github.com/caiosba/react-native-css
description {
margin-bottom: 20px;
font-size: 18px;
text-align: center;
color: #656656;
}
container {
padding: 30px;
margin-top: 65px;
align-items: center;
display: block;
}
// style.js
module.exports = require('react-native').StyleSheet.create(
{
"description": {
"marginBottom":20,
"fontSize":18,
"textAlign":"center",
"color":"#656656"
},
"container":{
"padding":30,
"marginTop":65,
"alignItems":"center"
}
}
);
superagent
fetch
superagent.get(url).withCredentials().end(
(err, response) => {...}
);
fetch(url, { headers: { credentials: 'include' } }).then(
response => { ... }
);
1) Autenticação via API (fetch) e armazenamento de token
2) Autenticação via React Native Cookie Manager (https://github.com/joeferraro/react-native-cookies)
import CookieManager from 'react-native-cookies';
CookieManager.setFromResponse('http://example.com',
'user_session=abcdefg; path=/; secure; HttpOnly')
.then((res) => {
callback(res);
});
3) Autenticação via WebView + postMessage
onMessage(event) {
const { data } = event.nativeEvent;
if (data) {
this.setState({ cookie: data });
}
}
render() {
return (
<WebView
source={{ uri: this.state.url }}
onMessage={this.onMessage.bind(this)}
injectedJavaScript="window.postMessage(document.cookie)"
/>
);
}
https://www.npmjs.com/package/react-native-share-menu
Módulo React Native que adiciona
sua aplicação ao menu "compartilhar" do aparelho e recebe URLs a partir de outros aplicativos
// Web
window.localStorage.setItem(key, value);
// Browser Extension
chrome.storage.sync.set({ key: value})
// Mobile
await AsyncStorage.setItem(key, value);
Implementar uma única função que abstraia para as diferentes plataformas
<!-- Web / Browser Extension -->
<div>
<button onClick={this.send.bind(this)}>Send</button>
</div>
<!-- React Native -->
<View>
<Button onPress={this.send.bind(this)} title="Send" />
</View>
https://github.com/necolas/react-native-web
Permite escrever os componentes em React Native e eles serão convertidos para React DOM
// .babelrc
{
"plugins": [
"react-native-web/babel"
],
"presets": [
"react-native"
]
}
// webpack
module.exports = {
resolve: {
extensions: ['.web.js', '.js',
'.web.jsx', '.jsx'],
alias: {
'react-native': 'react-native-web',
}
}
};
<!-- Hybrid -->
<IntlProvider locale={l} messages={msgs} textComponent={Text}>
<FormattedMessage defaultMessage="Original text" id="example" />
</IntlProvider>
<!-- Output: Web and Browser Extension -->
<span>Translated text</span>
<!-- Output: React Native -->
<Text>Translated text</Text>
https://github.com/yahoo/react-intl
Basta definir a propriedade textComponent do componente IntlProvider
import { Platform } from 'react-native';
let locale = 'en';
// Mobile
if (this.context.platform === 'mobile') {
// Android
if (Platform.OS === 'android') {
locale = NativeModules.I18nManager.localeIdentifier;
}
// iOS
else {
locale = NativeModules.SettingsManager.settings.AppleLocale;
}
}
// Web and Browser Extension
else {
locale = navigator.languages || navigator.language || navigator.userLanguage;
}
Identificando o idioma atual:
https://github.com/meedan/check-mark
htt//ca.ios.ba
slides.com/caiosba/jsdayrecife2017