React

React Basics

Install npm: create-react-app

create-react-app my-react-app //for creating the app

npm-run-eject // on a react project created with create-react-app, it will eject all the custom configurations about webpack and so on that are not showed by default

JS

// Arrow function don't bind the this keyword, so better use () => functions on React

< React.Fragment >

We can wrap everything on <React.Fragment> instead of a div in a react component if we don't want the extra <div> in our DOM

with JSX you can set const x = <h1>Zero</h1> and it will be rendered with react

States on classes

The state is private and internal to the component, The component that owns a piece of the state, should be the one modifying it.

// inside the class
state{
    myProperty: 0
};

// Read States
this.state.myProperty

// Set State
this.setState({
    myProperty: 1
});

Send Property onClick

handleIncrement = productId => {
  console.log(productId)
}
<button onClick={() => this.handleIncrement({ id: 1 })}>My Button</button>

Props on Components

Every react component has access to the property this.props, props are read only objects

// Setting Props for child on Parent component
<ChildComponent myProp={true} myString="My String" />

// Accessing props on Child Component
<p data-prop={this.props.myProp}>{this.props.myString}</p>

Passing Children

// Send Children Inside Children Tags on Parent
<ChildComponent>
  <h4>Content to be rendered on children</h4>
</ChildComponent>

// Access Children content on child component
{
  this.props.children
} // Renders <h4>Content to be rendered...

Communicating with Parent from Children

// On Parent, create method and send it as a prop in to the children
handleChildrenAction = () {
  console.log("Event Handler Called from child");
}
<ChildComponent onDelete={this.handleChildrenAction} />

// On Child
<button onClick={this.props.onDelete} /> // Event Handler Called from child

with attributes

// On Parent created method and send it as a prop in to the children
handleChildrenAction = (myId) {
  console.log(myId);
}
<ChildComponent onDelete={this.handleChildrenAction} />

// On Child
<button onClick={()=> this.props.onDelete(11)} /> // 11

Debug on Chrome

Find the chrome extension called React Developer Tools

Class component

class MyClassComponent extends Component {
  state = {
    myState: 0,
  }
  render() {
    return (
      <div>
        {this.state.myState}
        {this.props.myProp}
      </div>
    )
  }
}
export default MyClassComponent

Functional Component

// Stateless Functional Component
const MyFunctionalComponent = props => {
  return <div>{props.myProp}</div>
}

export default MyFunctionalComponent

Object Destructuring

On Class components, so you don't have to write this.props all the time you can set it like this:

class MyClassComponent extends Component {
  render() {
    const { myProp } = this.props
    return <div>{myProp}</div>
  }
}
export default MyClassComponent

On Functional components

const MyFunctionalComponent = ({ myProp }) => {
  return <div>{myProp}</div>
}

export default MyFunctionalComponent

Lifecycle Hooks

They load in this order, and can be used only on class components

* Mount
  - constructor
  - render
  - componentDidMount

* Update
  - render
  - componentDidUpdate

* Unmount
  - componentWillUnmount

Using componentDidUpdate, for example for making a new ajax call if value of prop changed:

componentDidUpdate(prevProps, prevState){
  console.log("prevProps", prevProps);
  console.log("prevState", prevState);
  if(prevProps.counter.value !== this.props.counter.value){
    // Ajax call and get new data from the server
  }
}

Working with objects

When working with objects, it is a good idea, in your child component, ask for the name of the objects properties in the child component properties, so, the components can be more flexible

// Parent Component calling Child
<ChildComponent textProperty="name" valueProperty="_id">

Later on Child Component

// Child Component
const MyChildComponent = props => {
  const { items, textProperty, valueProperty } = props
  return (
    <ul className="my-list">
      {items.map(item => (
        // Would be the same as item._id and item.name
        <li key={item[valueProperty]}>{item[textProperty]}</li>
      ))}
    </ul>
  )
}

Default props

while less props needed to be send to a component, more easily it is to work with, for that, you can set default props in your component

// My Text: Hello
...
const {myDefaultProperty} = props;
  return (
    <div>
    My Text: {myDefaultProperty}
    <div>
  )
};

MyComponentName.defaultProps = {
  myDefaultProperty: "Hello"
};

export default MyComponentName;

Post in progress...