Utilizamos propTypes
para tipar as props de um componente e garantir que não vão passar um tipo de dado errado, quebrando a aplicação.
Para fazer a validação de nossas props, o time do React disponibiliza uma biblioteca chamada prop-types
que nos fornece uma série de funções úteis para realizar este trabalho:
ComponentName.propTypes = {
propName: PropTypes.string,
propName: PropTypes.object.isRequired,
[…]
}
Outra maneira de utilizar propTypes
é adicionando uma propriedade estática ao objeto do componente:
class MyComponent extends React.Component {
static propTypes = {
propName: PropTypes.string,
propName: PropTypes.object.isRequired,
[…]
}
}
>>> ATENÇÃO! <<<
PropTypes
são desconsideradas quando utilizando a versão production
do React. Elas só funcionam na versão dev. As mensagens de erro nem aparecem em produção.
DICA: Posso utilizar o plugin babel-plugin-react-remove-prop-types
para remover as declarações de propTypes do meu código quando estiver fazendo o Build para produção.
A razão pela qual o React utiliza className
ou invés de class
para adicionar classes a um componente JSX, é o fato de que class
é uma palavra reservada na linguagem JavaScript. Utilizá-la para tal fim resultaria em muitas implicações (Ex: object destructuring (assignment), object literals etc).
>>> NOVO APRENDIZADO COM OBJECT DESTRUCTURING <<<
Quando "desestruturando objetos", não só eu posso extrair propriedades do mesmo como posso também, após selecionar as propriedades que desejo, armazenar o restante das propriedades não utilizadas dentro de um novo objeto/variável.
const myComponent = ({style, ...rest}) => (
<div
style={{ color: #333, ...style }}
{ ...rest }
/>
)
Naturalmente, nesta caso a variável rest
recebeu o restante das propriedades do objeto que não foram utilizadas.
Maneiras de se obter a referência de um elemento DOM (aqui utilizando o exemplo de um controle de formulário):
class MyComponent extends React.Component {
render() {
return (
);
}
}class MyComponent extends React.Component {
handleSubmit = (event) => {
event.preventDefault();
console.log(event.target[0].value);
console.log(event.target.elements.username.value);
console.log(this.inputNode.value); // Easiest way I guess.
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
type="text"
name="username"
ref={node => (this.inputNode = node)}
/>
</label>
<input type="submit" value="Submit"/>
</form>
);
}
}
Em resumo, a propriedade ref
serve para criar uma referência para o componente, para uso externo.
Quando trabalhando com controles de formulário e setando o atributo value
para alguma coisa (em especial, state), o React não me deixará alterar o valor do formulário na mão. O campo fica como que bloqueado.
Para conseguir alterá-lo, devo setar o valor do campo na mão, grande parte das vezes através do evento onChange
.
>>> DICA <<<
Para remover "falsy elements" de um array, basta utilizar arr.filter(Boolean)
.
http://www.devign.me/javascript-tip-remove-falsy-items-out-of-an-array
Action creators são funções cujo único trabalho é retornar um objeto que representa uma ação. Exemplo
const addTodo = (text) => ({
type: 'ADD_TODO',
id: (nextTodoId++).toString(),
text
});
Elas facilitam a leitura e a estruturação do código, de forma geral.
Se tivermos dados persistidos para servir de estado inicial da aplicação, poderemos passá-los no segundo parâmetro do método createStore
:
const persistedData = {
todos: [{
id: '0',
text: 'Welcome Back!',
completed: false
}]
};
const store = createStore(
todoApp,
persistedData
);
Para resolver problemas com IDs únicos em minha aplicação React, posso utilizar a biblioteca node-uuid
. Exemplo:
import { v4 } from 'node-uuid'
export const addTodo = (text) => ({
type: 'ADD_TODO',
id: v4(),
text
})
THROTTLING
Posso utilizar a função throttle()
da biblioteca lodash
para controlar o fluxo de chamadas para uma funçao, garantindo que ela não seja invocada mais do que uma vez a cada X
milisegundos. Exemplo:
// top of index.js
import throttle from 'lodash/throttle'
.
.
.
store.subscribe(throttle(() => {
saveState({
todos: store.getState().todos
})
}, 1000))
Quando utilizando react-router
, para ter uma URL limpa devo utilizar a função browserHistory
. Exemplo:
import { Router, Route, browserHistory } from 'react-router';
...
const Root = ({ store }) => (
<Provider store={store}>
<Router history={browserHistory}>
<Route path="/" component={App} />
</Router>
</Provider>
);
Para [email protected]
ou superior, o código fica assim:
import { BrowserRouter, Route } from 'react-router-dom'
const Root = ({ store }) => (
<Provider store={store}>
<BrowserRouter>
<Route path="/" component={App} />
</BrowserRouter>
</Provider>
);
Para marcar um parâmetro como opcional no react-router
, devo envolvê-lo em parênteses: <link to={'/(:filter)'} ... />