Skip to content

Instantly share code, notes, and snippets.

@DWboutin
Created March 11, 2016 16:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DWboutin/57e1911d9a3dde62e0c8 to your computer and use it in GitHub Desktop.
Save DWboutin/57e1911d9a3dde62e0c8 to your computer and use it in GitHub Desktop.
Tutoriel React après -> shouldComponentUpdate
import React from 'react';
import { connect } from 'react-redux';
import GroceryList from './GroceryList.react';
import ItemAdder from './ItemAdder.react';
import { changeListArray, itemSubmit, itemIncreasing, itemNameChange } from '../actions/grocery-list-actions';
import baseItemsList from '../utils/baseList';
class Application extends React.Component {
constructor(props) {
super(props);
this.handleItemSubmit = this.handleItemSubmit.bind(this);
this.handleNameChange = this.handleNameChange.bind(this);
}
componentWillMount() {
let { dispatch } = this.props;
dispatch( changeListArray(baseItemsList) );
}
componentWillReceiveProps(newProps) {
let { dispatch, groceryList } = this.props;
if(groceryList.itemList.length > 0 && newProps.groceryList.itemList.length > groceryList.itemList.length){
dispatch( itemIncreasing(true) );
setTimeout(() => {
dispatch( itemIncreasing(false) );
}, 3000);
}
}
handleItemSubmit(e) {
const { dispatch } = this.props;
e.preventDefault();
const form = document.getElementById('itemAdder');
const name = document.querySelector('.newItemName').value;
const type = document.querySelector('.newItemType').value;
dispatch(itemSubmit(name, type));
form.reset();
}
handleNameChange(index, name) {
let { dispatch } = this.props;
dispatch( itemNameChange(index, name) );
}
itemIncreaseFlash() {
if(this.props.groceryList.itemsIncreasing){
return (
<div style={{backgroundColor: '#ECCA4B'}}>Nouvel item</div>
);
}
}
render() {
const { groceryList } = this.props;
return (
<div>
<h1>{this.props.title}</h1>
{this.itemIncreaseFlash()}
<GroceryList items={groceryList.itemList} onNameChange={this.handleNameChange} />
<ItemAdder onItemSubmit={this.handleItemSubmit} />
</div>
);
}
}
Application.propTypes = {
title: React.PropTypes.string.isRequired
};
export default connect(state => ({
groceryList: state.groceryList
}))(Application);
import utils from '../utils/consts';
export function itemSubmit(name, itemType) {
return {
type: utils.ACTIONS.ITEM_SUBMIT,
name: name,
itemType: itemType
}
}
export function changeListArray(list) {
return {
type: utils.ACTIONS.CHANGE_LIST_ARRAY,
list: list
}
}
export function itemIncreasing(bool) {
return {
type: utils.ACTIONS.ITEM_INCREASING,
itemsIncreasing: bool
}
}
export function itemNameChange(index, name) {
return {
type: utils.ACTIONS.ITEM_NAME_CHANGE,
index,
name
}
}
import utils from '../utils/consts';
const initialState = {
itemList: [],
itemsIncreasing: false
};
export function groceryList(state = initialState, action = {}) {
switch(action.type) {
case utils.ACTIONS.ITEM_SUBMIT:
const itemList = [
...state.itemList,
{
name: action.name,
type: action.itemType
}
];
return {
...state,
itemList
};
case utils.ACTIONS.CHANGE_LIST_ARRAY:
return {
...state,
itemList: action.list
};
case utils.ACTIONS.ITEM_INCREASING:
return {
...state,
itemsIncreasing: action.itemsIncreasing
};
case utils.ACTIONS.ITEM_NAME_CHANGE:
const newItemList = [...state.itemList];
newItemList[action.index] = {...newItemList[action.index], name: action.name};
return {
...state,
itemList: newItemList,
};
default:
return state;
}
}
import React from 'react';
import ListItem from './ListItem.react';
class GroceryList extends React.Component {
constructor(props) {
super(props);
}
buildList (){
let list = this.props.items.map((item, index) => {
return (
<ListItem item={item} key={item.name + index} index={index} onNameChange={this.props.onNameChange} />
);
});
return list;
}
render () {
return (
<ul>{this.buildList()}</ul>
);
}
}
GroceryList.propTypes = {
items: React.PropTypes.array.isRequired
};
export default GroceryList;
import React from 'react';
class ItemAdder extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
$(".newItemType").chosen();
}
render () {
return (
<form id="itemAdder" onSubmit={this.props.onItemSubmit}>
<input type="text" name="newItemName" className="newItemName" />
<select name="newItemType" className="newItemType">
<option value="">Choose a type</option>
<option value="Fruit">Fruit</option>
<option value="Meat">Meat</option>
</select>
<button>Ajouter</button>
</form>
);
}
}
ItemAdder.propTypes = {
onItemSubmit: React.PropTypes.func.isRequired
};
export default ItemAdder;
import React from 'react';
/** Class for the List component */
class ListItem extends React.Component {
/**
* Pass the props to the parent
* @param {object} props - Properties of the component
*/
constructor(props) {
super(props);
this.state = {
modifyState: false,
};
}
changeSpanToInput(e) {
e.preventDefault();
this.setState({
modifyState: true
});
}
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.item.name !== this.props.item.name || nextState.modifyState !== this.state.modifyState) {
return true;
}
return false;
}
sendNameChange(e) {
let { index, onNameChange } = this.props;
onNameChange(index, $(e.target).parent().children('input').val());
this.setState({
modifyState: false
});
}
renderItem() {
let { item } = this.props;
if(this.state.modifyState === false){
return (<span className="name" onClick={this.changeSpanToInput.bind(this)}>{item.name}</span>);
} else {
return (<span className="name"><input type="text" defaultValue={item.name} /> <button onClick={this.sendNameChange.bind(this)}>Ok</button></span>);
}
}
render() {
let { item } = this.props;
return (
<li>
<input type="checkbox" />
{this.renderItem()}
<em>{item.type}</em>
</li>
);
}
}
/**
* Required props
* @property {items} - An array list of items
*/
ListItem.propTypes = {
item: React.PropTypes.object.isRequired
};
export default ListItem;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment