Skip to content

Instantly share code, notes, and snippets.

@1UC1F3R616
Last active January 13, 2022 10:28
Show Gist options
  • Save 1UC1F3R616/fc358492ca393719c56b339df45f9c43 to your computer and use it in GitHub Desktop.
Save 1UC1F3R616/fc358492ca393719c56b339df45f9c43 to your computer and use it in GitHub Desktop.

npx create-react-app myapp

// Import the React and ReactDOM libraries
// Create a react component
// Take the react component and show it on the screen
- setting states in Class based component is done by simply `state = { var1: [], var2: 'value' }`
- Do not set state 2nd time instead alter the only declaration
- State change is done like this `this.setState({var2: null})`
- to pass props inside a component from top to bottom --> `<componentName myProp={key1: value}>`
- To access the props --> (props) => {return <div>props.key1</div>}
- You can use destrcturing

Simple index.js (Functional Based)

// Import the React and ReactDOM libraries
import React from 'react';
import ReactDOM from 'react-dom';

// Create a react component
const App = () => {
    return <div>Hi There!</div>
}

// Take the react component and show it on the screen
ReactDOM.render(
    <App />, document.querySelector('#root')
);

Adding Components

  • CommentDetail is a function that has JSX inside it and it is imported from another file
const App = () => {
    return (
        <div className="ui container comments">
            <CommentDetail />
            <CommentDetail />
            <CommentDetail author="Kush" />
        </div>
    );
};

Simple index.js (Class Based)

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
    
    render() {
        window.navigator.geolocation.getCurrentPosition(
            (position) => console.log(position),
            (err) => console.log(err)
        )
        return <div>Latitude: </div>
    }
}

ReactDOM.render(
    <App />,
    document.querySelector('#root')
)

Simple Example using States and Conditional rendering

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
    // Initializing State
    constructor(props) {
        super(props);

        // only time we do direct assignment
        this.state = { lat: null, errorMessage: '' };

        window.navigator.geolocation.getCurrentPosition(
            (position) => {
                this.setState({lat: position.coords.latitude})},
            (err) => {
                this.setState({errorMessage: err.message})
            }
        )
    }
    
    render() {
        if (this.state.errorMessage && !this.state.lat) {
            return <div>Error: { this.state.errorMessage }</div>
        } else if (!this.state.errorMessage && this.state.lat) {
            return <div>Lat: {this.state.lat}</div>
        } else {
             return (
                <div>
                Latitude: { this.state.lat }
                <br/>
                Error: { this.state.errorMessage }
                </div>
                );
        }

    }
}

ReactDOM.render(
    <App />,
    document.querySelector('#root')
)

Component Lifecycle

  constructor (good place to do one-time setup)
    ⬇
  render (Avoid doing anything beside returning JSX)
  `content visible on screen`
    ⬇
  componentDidMount (good place to do data loading)
  `Sit and wait for updates...`
    ⬇
  componentDidUpdate (Good place to do more data-loading when state/props change)
  `Sit and wait until this component is not longer shown`
    ⬇
   componentWillUnmount (Good place to do cleanup, especially for non-React stuff)

Other lifecycle methods (rarely used)

  • shouldComponentUpdate
  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

Event Handlers: Handling events with React elements is very similar to handling events on DOM elements

  • onClick User clicks on something : A div can be clicked
  • onChange User changes text in an input
  • onSubmit User submits a form

React Refs

  • Gives access to a single DOM element
  • We create refs in the constructor -> Assign them to instance variables -> then pass to a particular JSX element as props

React Hooks

Hooks System

  • useState: Function that lets you use state in a functional component
  • useEffect: Function that lets you use something like lifecycle methods in a functional component
  • useRef: Function that lets you create a ref in a funcitonal component

Hooks are way to write resuable code, instead of more classic techniques like inheritance

10 Primitive Hooks (Not a Technical term)

  • useState
  • useEffect
  • useContext
  • useReducer
  • useCallback
  • useMemo
  • useRef
  • useImperativeHandle
  • useLayoutEffect
  • useDebugValue

Custom Hook (Example)

  • useTranslate
    • useState
    • useEffect

Class Components v/s Function Components

- Class Components Function Components
Initalization state = { activeIndex: 0 } useState(0)
Refernce this.state.activeIndex activeIndex
Updates this.setState({ activeIndex: 10 }) setActiveIndex(10)

Examples are added in comments


Redux

  • React is to render and present data to user not handling

What is Redux?

  • State Managment Library
  • Makes creating complex applications easier
  • Not required to create a React App!
  • Not explicitly designed to work with React!

Redux Cycle

Action Creator
    ⬇
Action
    ⬇
Dispatch
    ⬇
Reducers
    ⬇
State
@1UC1F3R616
Copy link
Author

1UC1F3R616 commented Jun 22, 2020

  • Semantic UI CDN link
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">

@1UC1F3R616
Copy link
Author

1UC1F3R616 commented Jun 22, 2020

Rules of State

  • Only usable with class components
  • 'State' is a JS object that contains data relevant to a component
  • Updating 'state' on a component causes the component to (almost) instantly rerender
  • State must be initialized when a component is created
  • State can only be updated using the function 'setState'

Initializing State using Constructor

class App extends React.Component {
    // Initializing State
    constructor(props) {
        super(props);

        this.state = { lat: null };
    }
    
    render() {
        window.navigator.geolocation.getCurrentPosition(
            (position) => console.log(position),
            (err) => console.log(err)
        )
        return <div>Latitude: </div>
    }
}

@1UC1F3R616
Copy link
Author

  • Initializing State way 1
class App extends React.Component {
     constructor(props) {
         super(props);

         // only time we do direct assignment
         this.state = { lat: null, errorMessage: '' };
     }
}
  • Initializing State way 2
class App extends React.Component {
state = { lat: null, errorMessage: '' }
}
  • Check at Babel
  • Babel magic in way 2

@1UC1F3R616
Copy link
Author

Handling User Input from Forms and Events

  • Uncontrolled Component
import React from "react";

class SearchBar extends React.Component {

    onInputChange(event) {
        console.log(event.target.value)
    }

    render() {
        return (
            <div className="ui segment">
                <form className="ui form">
                    <div className="field">
                        <label>Image Search</label>
                        <input type="text" onChange={this.onInputChange}/>
                    </div>
                </form>
            </div>
        );
    }
}

export default SearchBar;
  • Controlled Component
import React from "react";

class SearchBar extends React.Component {
    state = { term: "" };

    render() {
        return (
            <div className="ui segment">
                <form className="ui form">
                    <div className="field">
                        <label>Image Search</label>
                        <input
                            type="text"
                            value={this.state.term}
                            onChange={(e) =>
                                this.setState({ term: e.target.value })
                            }
                        />
                    </div>
                </form>
            </div>
        );
    }
}

export default SearchBar;

@1UC1F3R616
Copy link
Author

Handling form submission & this issue

import React from "react";

class SearchBar extends React.Component {
    constructor(props) {
        super(props);
        this.onFormSubmit = this.onFormSubmit.bind(this);
    }

    state = { term: "" };

    onFormSubmit(event) {
        event.preventDefault();
        console.log(this.state.term)
    }

    render() {
        return (
            <div className="ui segment">
                <form onSubmit={this.onFormSubmit} className="ui form">
                    <div className="field">
                        <label>Image Search</label>
                        <input
                            type="text"
                            value={this.state.term}
                            onChange={(e) =>
                                this.setState({ term: e.target.value })
                            }
                        />
                    </div>
                </form>
            </div>
        );
    }
}

export default SearchBar;

Solving same problem using Arrow Function

  • function gives broken value for this
import React from "react";

class SearchBar extends React.Component {
    state = { term: "" };

    onFormSubmit = (event) => {
        event.preventDefault();
        console.log(this.state.term)
    }

    render() {
        return (
            <div className="ui segment">
                <form onSubmit={this.onFormSubmit} className="ui form">
                    <div className="field">
                        <label>Image Search</label>
                        <input
                            type="text"
                            value={this.state.term}
                            onChange={(e) =>
                                this.setState({ term: e.target.value })
                            }
                        />
                    </div>
                </form>
            </div>
        );
    }
}

export default SearchBar;

Method 3rd to solve the same problem

import React from "react";

class SearchBar extends React.Component {
    state = { term: "" };

    onFormSubmit(event){
        event.preventDefault();
        console.log(this.state.term)
    }

    render() {
        return (
            <div className="ui segment">
                <form onSubmit={(event) => this.onFormSubmit(event)} className="ui form">
                    <div className="field">
                        <label>Image Search</label>
                        <input
                            type="text"
                            value={this.state.term}
                            onChange={(e) =>
                                this.setState({ term: e.target.value })
                            }
                        />
                    </div>
                </form>
            </div>
        );
    }
}

export default SearchBar;

@1UC1F3R616
Copy link
Author

Insurance Policy Code [Redux]

console.clear();

// People dropping off a form (Action Creators)
const createPolicy = (name, amount) => {
  return { // Action (a form in our analogy)
    type: 'CREATE_POLICY',
    payload: {
      name: name,
      amount: amount
    }
  };
};

const deletePolicy = (name) => {
  return {
    type: 'DELETE_POLICY',
    payload: {
      name: name
    }
  };
};

const createClaim = (name, amountOfMoneyToCollect) => {
  return {
    type: 'CREATE_CLAIM',
    payload: {
      name: name,
      amountOfMoneyToCollect: amountOfMoneyToCollect
    }
  };
};


// Reducers (Departments!)
const claimsHistory = (oldListOfClaims = [], action) => {
  if (action.type === 'CREATE_CLAIM') {
    // we care about this action (FORM!)
    return [...oldListOfClaims, action.payload];
  }
  
  // we don't care the action (form!!)
  return oldListOfClaims;
};

const accounting = (bagOfMoney = 100, action) => {
  if (action.type === 'CREATE_CLAIM') {
    return bagOfMoney - action.payload.amountOfMoneyToCollect;
  } else if (action.type === 'CREATE_POLICY') {
    return bagOfMoney + action.payload.amount;
  }
  
  return bagOfMoney;
};

const policies = (listOfPolicies = [], action) => {
  if (action.type === 'CREATE_POLICY') {
    return [...listOfPolicies, action.payload.name];
  } else if (action.type === 'DELETE_POLICY') {
    return listOfPolicies.filter(name => name !== action.payload.name);
  }
  
  return listOfPolicies;
};

const { createStore, combineReducers } = Redux;

const ourDepartments = combineReducers({
  accounting: accounting,
  claimsHistory: claimsHistory,
  policies: policies
});

const store = createStore(ourDepartments);

createPolicy('Alex', 20)
createClaim('Alex', 120)
deletePolicy('Alex')

store.dispatch(createPolicy('Alex', 20));
store.dispatch(createPolicy('Jim', 30));
store.dispatch(createPolicy('Bob', 40));

// store.dispatch(createClaim('Alex', 120));
// store.dispatch(createClaim('Jim', 50));

// store.dispatch(deletePolicy('Bob'));

console.log(store.getState());

@1UC1F3R616
Copy link
Author

Redux

npm install --save redux react-redux

@1UC1F3R616
Copy link
Author

1UC1F3R616 commented Jul 11, 2020

Props pass from Top to Bottom, But to pass from bottom to top we need a trick

  • searchbar.js
import React from 'react';

class SearchBar extends React.Component {
  state = { term: '' };

  onInputChange = event => {
    this.setState({ term: event.target.value });
  };

  onFormSubmit = event => {
    event.preventDefault();

    this.props.onFormSubmit(this.state.term);
  };

  render() {
    return (
      <div className="search-bar ui segment">
        <form onSubmit={this.onFormSubmit} className="ui form">
          <div className="field">
            <label>Video Search</label>
            <input
              type="text"
              value={this.state.term}
              onChange={this.onInputChange}
            />
          </div>
        </form>
      </div>
    );
  }
}

export default SearchBar;
  • App.js
import React from 'react';
import SearchBar from './SearchBar';
import youtube from '../apis/youtube';
import VideoList from './VideoList';
import VideoDetail from './VideoDetail';

class App extends React.Component {
  state = { videos: [], selectedVideo: null };

  componentDidMount() {
    this.onTermSubmit('buildings');
  }

  onTermSubmit = async term => {
    const response = await youtube.get('/search', {
      params: {
        q: term
      }
    });

    this.setState({
      videos: response.data.items,
      selectedVideo: response.data.items[0]
    });
  };

  onVideoSelect = video => {
    this.setState({ selectedVideo: video });
  };

  render() {
    return (
      <div className="ui container">
        <SearchBar onFormSubmit={this.onTermSubmit} />
        <div className="ui grid">
          <div className="ui row">
            <div className="eleven wide column">
              <VideoDetail video={this.state.selectedVideo} />
            </div>
            <div className="five wide column">
              <VideoList
                onVideoSelect={this.onVideoSelect}
                videos={this.state.videos}
              />
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Heresearchbar component has to be passing its data to App component which then further processes the data and pass it.
Here 'searchbar' is at bottom and App is at the top

searchbar passes the data to props when form is submited, props is passed to searchbar from App

this.props.onFormSubmit(this.state.term); : searchbar passing to App
<SearchBar onFormSubmit={this.onTermSubmit} />,

onTermSubmit = async term => {
    const response = await youtube.get('/search', {
      params: {
        q: term
      }
    });

    this.setState({
      videos: response.data.items,
      selectedVideo: response.data.items[0]
    });
  };

Here App passes the coming data to a function


  • onVideoSlelect is another example of such behaviour in videos web app

@1UC1F3R616
Copy link
Author

React Hook using State Example

import React, { useState } from "react";

const Accordion = ({ items }) => {
    const [activeIndex, setActiveIndex] = useState(null);

    const onTitleClick = (index) => {
        setActiveIndex(index);
    };

    const renderedItems = items.map((item, index) => {
        return (
            <React.Fragment key={item.title}>
                <div
                    className="title active"
                    onClick={() => onTitleClick(index)}
                >
                    <i className="dropdown icon"></i>
                    {item.title}
                </div>
                <div className="content active">
                    <p>{item.content}</p>
                </div>
            </React.Fragment>
        );
    });

    return (
        <div className="ui style accordion">
            {renderedItems}
            <h1>{activeIndex}</h1>
        </div>
    );
};

export default Accordion;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment