Miscellaneous React js notes

useEffect Notes

useEffect is called on initial load and every update after unless an empty dependency array is entered.. then it is only performed on first load:

 

For ajax calls on initial loads or in useEffect in general..async/await is only allowed if done in this way:

useEffect & setState

useEffect generally would get the “stale” state value however we can pass in a callback to the setState function in order to recieve/use the previous states value

 

The remaining problem with this is that you can only access the previous state value if you are setting (setSomeState) it. One work around that is provided is to use Refs

Using useRefs for current state value in useEffect

Refs exist outside of the re-render cycle and there for their actual current value isn’t effected by re-renders and so the value at ref.current will stay “current”. So the ref.current value will be what it was set last and not being reset or altered by a re-render. However, refs aren’t reactive.

The problem with this approach is that refs aren’t reactive and so shouldn’t be used like how <div>The count is: {count}</div> is displayed because the actual value that is displayed (the counting would still happen behind the scene tho ) won’t update until the component is re-rendered.

React Router

Import react-router-dom to use for web. Wrap <BrowserRouter></BroswerRouter> around <App/> in the index.js

To create routes you would do the following:

 

Link vs NavLink

To link to a route you can use Link or NavLink. The difference mostly is that Link will just create a <a> element pointing to the route ( which doesn’t actually issue a GET request like a link normally would ). Navlink will do the same thing but it is to be used in menus because you can set a prop in Navlink to indicate the “active” route so it can be styled properly.

 

Passing a prop to a route ( render vs component props )

 

URL Parameters with Router

When a route is declared and component/render/children is used, 3 things are passed to component/render/children under one component.. — history, location , match

So we can do the following to extract the parameter in a given route

 

Redirects

Can use Redirect component from react-router-dom .

 

Redirect programmatically 

This is done by pushing on the browser history stack. In order to be able to do that, the routeProps has to be passed down when the <Route/> is created. This is done automatically if using componenet={SomeComponent} but needs to be passed manually if done via render instead. i.e. You would only need to use render if you want to pass other props to the Route’s component.

 

Some differences of history.push vs <Redirect>

<Redirect /> won’t change the back button so if you redirect to a url that goes to a 404 then hitting the back button won’t bring them back to the url that will re-redirect to the 404 page. history.push will make the back button to the route that was pushed – so, if history.push to a route that goes to a 404 then hitting the back button will bring it back to the route that took it to the 404 and will be a endless loop.

Redirecting via history.push when the component has no route its self and so no routeProps – use withRouter

 

props.history.goBack() and props.history.goFoward()

These methods are available if needed to create functionality in the app similiar to the browsers forward and back button.

 

React Context API

Components can easier share values/functions by being wrapped in a Context.Provider component. Any component that uses that particular Context will be re-rendered when that Context’s value changes. This may cause un-wanted re-renders.

An example of using the Context Hook:

 

One issue with above is the todoContext using an object for the values ( values={{count:100}} ) , this will cause needless re-renders because the object will be rebuilt every time.

Setting Disabled attribute based on a function (computed property) that returns a boolean 

 

Conditionally show a component based on a state array not being empty.

Casting the input.Values.length as a Boolean enables this to be possible. Without casting , it would return a 0 to the screen which is not what is desired.