ANA LUIZA BASTOSgithub.com/anabastos@naluhh@anapbastosSoftware Developer na Quanto ecientista da computação naPUC-SPanabastos.me
View Slide
JSLADIESfb.com/jsladiesbrtwitter.com/jsladiesspmeetup.com/JsLadies-BR/LAMBDA.IOt.me/lambdastudygroupgithub.com/lambda-study-group/meetup.com/Lambda-I-O-Sampa-Meetup/
INTRODUÇAO AO RAMDA COMREACT
Biblioteca que foi pensadapara tornar mais fácil ojavascript funcional
REACT + RAMDA
USOSCONVENIÊNTES/REFACTORZINHOS
PQ RAMDA?
● faz uso de conceitos funcionais● 100% imutável● ganho em performance● elegante● point-free● etc
● Lists(map, filter, reduce, contains, replace,passAll, crop, flatten, find)● Maths(inc, add, mean, sum)● String(split, replace)● Logics(equals, cond, not)● Relation(intersection, clamp, gt, lt)● Functions(curry, pipe, compose, ifElse, etc)
TODAS AS FUNÇÕESSÃO CURRIED
const add = (x, y) => x + yadd(1, 2); // 3add(1) // Error
(curry)
const curryAdd = R.curry((x, y) => x + y))curryAdd(1, 2); // 3const addOne = curryAdd(1); // FunctionaddOne(2) // 3
STATELESSFUNCTIONStodo list
const Container = children => ({children});const List = children => ({children});const ListItem = ({ id, text }) => ({text});
const TodoItem = {id: 123,text: 'Comprar pão'};Container(List(ListItem(TodoItem)));Comprar pão
COMPOSE HIGHORDER COMPONENTS(pipe / compose)
PIPE / COMPOSE:compõe funções de formasequencial
function1 function2
ComposedFunction
PIPECOMPOSE
// Container(List(ListItem(TodoItem)));const TodoList = R.compose(Container,List,ListItem);TodoList(TodoItem);Comprar pão
const TodoItems = [{...}, {...}, {...}]const TodoList = R.compose(Container,List,R.map(ListItems));TodoList(TodoItems);Comprar pãoPagar boletosIr pra react sp na neon
const TodoItems = [{...}, {...}, {...}]const TodoList = R.compose(Container,List,R.map(ListItems),R.sort(byId),);const byId = R.ascend(R.prop(‘id’))TodoList(TodoItems);
const sortedListItems = R.pipe(R.sort(byId),R.map(ListItems),)
const TodoItems = [{...}, {...}, {...}]const TodoList = R.compose(Container,List,sortedListItems,);TodoList(TodoItems);
COMPOSIÇAO DEPROMISE(pipeP / composeP)
const todoList = R.pipeP(getUserById,getTodos,funçãoAsyncQueFazWhatever,) // Promiseawait todoList(‘123’)
DATA HANDLING(Evolve, ApplySpec)
EVOLVE
R.evolve({email: R.toLower,phone: R.replace(‘-’, ‘’),name: R.trim,})(data)
// state {// …,// selected: false,// … ,// }onToggleSelected() {this.setState((prevState) => ({...prevStateselected: !prevState.selected}))}
onToggleSelected() {this.setState(R.evolve({ selected: R.not }))}
APPLY SPEC
const createObj = R.applySpec({counter: R.inc,userData: { phone: R.trim},})createObj(0, “ 98499-1900”)// {1, userData{ phone: “9849919000”}}
const handlePhone = R.pipe(R.split(‘-’),R.join,R.replace(/[^0-9]/, ‘’),algumaCoisa, // (str) => {str})
const createObj = R.applySpec({counter: R.inc,userData: { phone: handlePhone},})
IMMUTABLE STATE(lenses)
currentState -> newState0- +
const counterLens = R.lensProp('counter');counterLens(state) //{ counter: 0 }
// state = { a: { b: { counter: 0 }const counterLens = R.lensPath(['a','b','counter']);counterLens(state)
// const state = {counter : 0}// viewconst getCounter = R.view(counterLens) // 0getCounter(state) // 0// setconst setCounter = R.set(counterLens, 1)setCounter(state) // 1// overconst incCounter = R.over(counterLens, R.inc)incCounter(state) // 1
// sem lens :(this.setState((prevState) => {({ counter: prevState.a.b.counter++ }))}// com lens :)this.setState(incCounter)
render() {const count = getCounter(this.state)return ({count})}
● Se foca em apenas umapropriedade do objeto● Não muta a propriedade● Consigo lidar caso a propriedadeé undefined● Torna bem mais declarativo
SWITCH CASE / IF(cond)
switch (action.type) {case 'INCREMENT':return state + action.payload;case 'DECREMENT':return state - action.payload;default:return state;}
const load = R.cond([[R.equals('INCREMENT'), R.inc(state)],[R.equals('DECREMENT'), R.dec(state)],[R.T, R.always(state)],])load(action.type)
const Content = (props) => {if(props.loading) {return }if(props.items.length == 0) {return }return }
const Content = R.cond([[R.prop('loading'), Loading],[R.isEmpty(props.items), Missing],[R.T, Section],])Content(props)
STATIC COMPONENT(always)
const Loading = () => (Loading)ReactDOM.render(, rootEl)
const Loading = R.always(Loading)ReactDOM.render(, rootEl)
STYLEDCOMPONENTS(path)
const Name = () => styled.Text`font-weight: bold,font-size: 18px,color: ${props => props.theme.primaryColor}`
const Name = () => styled.Text`font-weight: bold,font-size: 18px,color: ${R.path([‘theme’, ‘primaryColor’])}`
● memoize(Function)● merge(List, Obj)● tryCatch(Function)● anyPass / AllPass(List)● flatter(List)
RAMDASCRIPT
Nem sempre você tem umtrade-off em legibilidade.
5 + 10 // 15R.add(5, 10) // 15[5, 10].reduce((x, y) => {x + y}, 0)[5, 10].reduce(add, 0)
const obj = {x: 10}R.prop(‘x’)(obj) // 10obj.x // 10R.sortBy(R.prop(‘x’))R.prop(‘x’)({}) // undefined
BOM TOOLBOX
COOKBOOK
● Rambda - github.com/selfrefactor/rambda● Ramda-fantasy - github.com/ramda/ramda-fantasy● Ramda React Redux Patterns -tommmyy.github.io/ramda-react-redux-patterns/● Thinking Ramda -randycoulman.com/blog/2016/05/24/thinking-in-ramda-getting-started● Ramda - Derek Stavis(Pagar.me talks)● Hey Underscore, You’re doing it wrong - Brian Lonsdorf.
t.me/lambdastudygroupgithub.com/lambda-study-group
OBRIGADA :)https://speakerdeck.com/anabastosanabastos.me