My Daily Quick Notes

Hello Friends,

In this section I would like to share what I have learnt for the day in the form of quick notes. This will help me in future when I want to quickly refer back some concepts which I have learnt already.

Hopefully, this may help you guys on learning something new.

Till Now:

Below are the details which I have learnt for the past few weeks and still stays in my mind. From tomorrow I will try to put daily update.

React Notes:


Below is my simple code to understand the state and props of React component. We can copy paste the code in above URL to execute it.

Code:


const Header = () => {

  return <h2 className="header">Weather Forecast App</h2>

}

const InputForm = (props) => {

  const [cityName, setCityName] = useState('');



  const handleSubmit = (e) => {

    e.preventDefault();

    props.onClick(cityName);

    setCityName('');
  }
  return (
    <form onSubmit={handleSubmit}>
      <input 
        type="text" 
        value={cityName} 
        onChange={(e) => { setCityName(e.target.value) }} 
        placeholder="Enter City..." 
      />
      <button>Search</button>
    </form>
  )
}
const DisplayWeather = (props) => {
  return (
    <ul>
      <li>{ props.city }</li>
    </ul>)
}
const App = () => {
  const [city, setCity] = useState('Singapore');
  const handleCity = (newCity) => {
    setCity(newCity);
  }
  const changeCity = () =>{ setCity('newCity')};
  return (
    <div>
      <Header/>
      <InputForm onClick={handleCity}/>
      <DisplayWeather city={city} />
      <button onClick={changeCity}>Change</button>
    </div>
  )
}

ReactDOM.render(<App/>, mountNode);


PureComponent -> It does shallow comparison of props is true then it renders else no [ this works only for class component ]

React.memo(SampleFunctionComponent) --> it will act as PureComponent

--------Ref------------

this.sampleRef = React.createRef() --> to create a Ref

<input type="text" ref={this.sampleRef}/>  --> Now using sampleRef variable we can access this DOM element

this.sampleRef.current.focus()
this.sampleRef.current.value


Another way of creating ref using callback function

e.g.:

cbRef = null
this.setCbRef = (element) => {
  this.cbRef = element
}

Now to assign this to DOM node we can assign setCbRef

<input type="text" ref={this.setCbRef} />   --> when we call setCbRef , the input element will  be passed as argument which then be assigned to cbRef

then, this.cbRef.focus()  , this.cbRef.value so on    -> here we do not have current property i.e this.cbRef.current.value


---Ref for our own Class Component----

since we create our custom component, we can create Ref for those as well. ie if we create UserComponent then we display using <UserComponent />

So if <ParentComponent> is displaying <UserComponent/> then we can create Ref for this UserComponent (in Parent) and access the function of UserComponent

e.g


this.childRef = React.createRef()

<UserComponent ref={this.childRef} />

then this.childRef.current.anyFunctionOfChild()

---ForwardingRef----

in Parent

this.childRef = React.createRef()

<UserComponent ref={this.childRef} />

then this.childRef.current.focus() -> here we are directly calling DOM function. This is achieved by forwarding the ref to child

in Child

const UserComponent = React.forwardRef((props, ref) => {
  return (
    <div><input type="text" ref={ref} />
  )
})


---------Portal-------

Ability to create a DOM node outside our root node

e.g.:

this line of code can be in return statement of any component

ReactDom.createPortal(<h1>Test</h1>, document.getElementById('some-other-root'))

--------HOC--------

HigherOrderComponents - Need to share common functionality between components

cosnt newComponent = HOC(orginalCompoent)
const IronMan = withSuit(TonyStark)


sample HOC:

import React from 'react';

const withCounter = (OriginalComp) => {
  class NewComponent extends React.Component {

    render() {
      return <OriginalComp name="hoc"/>
    }
  }
  return NewComponent
}
export default withCounter


Now, assume we have another component HoverCounter then we export that with the help of withCounter (like below), then we can access the name prop = "hoc"

export default withCounter(HoverCounter);


---- Render Prop -------

It means sharing code between React Components using prop whose value is a function


---- Context API --------

1. Create the context
  // UserContext.js
   const UserContext = React.createContext()
   const UserProvider = UserContext.Provider
   const UserConsumer = UserContext.Consumer
   export { UserProvider, UserConsumer }

2. Provide
  in APP component ( or any component under which we need to pass any prop)
  const user = {"name":"yusuf", "age":30}
  <UserProvider value={...user}>
    <ComponentC />
  </UserProvider>

3. Consume

  in Any component (ComponentC or its child)
  <UserConsumer>
    {
      (userObj) => {
        return <div>{userObj.name} {userObj.age}</div>
      }
    }
  </UserConsumer>



useContext & useReducer example
--------------------------------

The idea is, the context is kind of carrier. Meaning that we can pass the things under value argument of Context.Provider and it's childern can access that.

Our objective is to create a global state component and pass the state and dispatch (obtained via useReducer) to its children

Example:

CountState.js
----------------

import { createContext } from 'react';

// creating a context
export const CountContext = React.createContext()

const CountState = (props) => {

  // our initial global state
  const initialState = { count: 0}

  // reducer function
  const reducer = (state, action) => {
    switch(action.type) {
      case 'I': return { count: state.count+1}
      case 'D': return { count: state.count-1}
      case 'R': return { count: 0}
      default: return state
    }
  }

  // useReducer -> is actually another way of managing state (instead of useState)
  // with this one line of code, any changes to the state should be managed by reducer via dispatch method
  const [ state, dispatch ] = React.useReducer(reducer, initialState)

  // Now lets pass this state and dispatch to its children
  // in React children refers to all of its sub component , Now we will wrap our      // main app component with this CountState component so that, all of our App and    // its sub component will be child of CountState and the state and dispatch will    // be passed
  return (
    <CountContext.Provider value={{ state, dispatch}}>
      { props. children }
    </CountContext.Provider>)
}



// some nested components

const CompA = () => {
  return <div>Component-A</div>
}

const CompB = () => {
  return <div><CompD/></div>
}

const CompC = () => {
  return <div><CompE/></div>
}

// in any sub component if we want to access the state and dispatch then 
// we use useContext we can see the context itself was exported in CountState

import { CountContext } from './CountState'     
const CompD = () => {
  const { state, dispatch } = React.useContext(CountContext)
  return (
    <div>Component-D
      <button onClick={()=>{dispatch({type:'I'})}}>Inc</button>
      <button onClick={()=>{dispatch({type:'D'})}}>Dec</button>
      <button onClick={()=>{dispatch({type:'R'})}}>Reset</button>
    </div>)
}

const CompE = () => {
  return <div><CompF/></div>
}

const CompF = () => {
  const { state, dispatch } = React.useContext(CountContext)
  return (
    <div>Component-F
      <button onClick={()=>{dispatch({type:'I'})}}>Inc</button>
      <button onClick={()=>{dispatch({type:'D'})}}>Dec</button>
      <button onClick={()=>{dispatch({type:'R'})}}>Reset</button>
    </div>)
}


// main App component

const App = () => {
  
  // By providing CountState as parent component, now we can access the state and dispatch in any sub components of A, B or C or its childs 
  return (
    <CountState>
      <div>
        <CompA/>
        <CompB/>
        <CompC/>
      </div>
    </CountState>)
}

ReactDOM.render(<App/>,mountNode)

No comments:

Post a Comment