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)'} ... />