903 Matching Annotations
  1. Last 7 days
  2. Nov 2022
    1. ReactJS vs React Native: A Comparison Guide for 2023

      React Native vs ReactJS have become two of the most popular web development technologies in the world. The main difference between ReactJS and React native is that ReactJS is JavaScript while ReactJS native is mobile app development framework. Let’s take a closer look at the advantages and disadvantages of ReactJS vs React native. https://bit.ly/3fo6Lwl

  3. Oct 2022
    1. Angular vs React: A Complete Comparison Guide for 2023

      Want to know the difference between React and Angular? Is yes then check out this blog to know the actual difference of both technologies. Both are incredibly strong, advancing web programming by enhancing, facilitating, and accelerating development. https://bit.ly/3rSRHtl

  4. Sep 2022
  5. Aug 2022
    1. Chadeau-Hyam, M., Wang, H., Eales, O., Haw, D., Bodinier, B., Whitaker, M., Walters, C. E., Ainslie, K. E. C., Atchison, C., Fronterre, C., Diggle, P. J., Page, A. J., Trotter, A. J., Ashby, D., Barclay, W., Taylor, G., Cooke, G., Ward, H., Darzi, A., … Elliott, P. (2022). SARS-CoV-2 infection and vaccine effectiveness in England (REACT-1): A series of cross-sectional random community surveys. The Lancet Respiratory Medicine, 0(0). https://doi.org/10.1016/S2213-2600(21)00542-7

    1. And in our case, we want it to keep track of our storage object. So let's also create a usePeristentContext hook.

      ```js import { useMutation, useQuery, useQueryClient } from 'react-query';

      export default function usePersistentContext(key) { const queryClient = useQueryClient();

      const { data } = useQuery(key, () => localStorage.getItem(key));

      const { mutateAsync: setValue } = useMutation( (value) => localStorage.setItem(key, value), { onMutate: (mutatedData) => { const current = data; queryClient.setQueryData(key, mutatedData); return current; }, onError: (_, __, rollback) => { queryClient.setQueryData(key, rollback); }, } );

      return [data, setValue]; } ```

      js function SetContext() { const [value, setValue] = usePersistentContext('item_context'); return ( <button onClick={() => setValue(value === 'on' ? 'off' : 'on')}> Click me {value} </button> ); }

  6. Jul 2022
    1. this.handleChange

      change事件更新state,也就是用户输入的value,这就是受控组件

    2. this.state.value

      value随用户输入而改变state

    1. 想要将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入 ReactDOM.createRoot(): const root = ReactDOM.createRoot( document.getElementById('root') ); const element = <h1>Hello, world</h1>; root.render(element);

      createRoot()返回一个ReactDOM对象,该对象具有render方法。

    1. React may batch multiple setState() calls into a single update for better performance.

      so its not an actual race condition b/w two parallel instructions, but rather just a result of an optimisation performed by react

  7. Jun 2022
    1. If the component wrapped with memo re-renders, it means that one of its properties changes.
  8. May 2022
    1. React Helmet

      ```js import {Helmet} from "react-helmet";

      const Demo = props => ( <br /> <div className="application"> <Helmet> <script src="/path/to/resource.js" type="text/javascript" /> </Helmet> ... </div>

      ); ```

      DOM Method

      ```js componentDidMount () { const script = document.createElement("script"); script.src = "/path/to/resource.js"; script.async = true; document.body.appendChild(script); }

      export const appendScript = (scriptToAppend) => { const script = document.createElement("script"); script.src = scriptToAppend; script.async = true; document.body.appendChild(script); }

      class Demo extends React.Component { componentDidMount () { appendScript("/path/to/resource.js"); } } ```

      React Hooks

      js useEffect(() => { const script = document.createElement('script'); script.src = "/path/to/resource.js"; script.async = true; document.body.appendChild(script); return () => { document.body.removeChild(script); } }, []);

      ```js import { useEffect } from 'react'; const importScript = resourceUrl=> { useEffect(() => { const script = document.createElement('script'); script.src = resourceUrl; script.async = true; document.body.appendChild(script); return () => { document.body.removeChild(script); } }, [resourceUrl]); };

      const Demo = props => { importScript("/path/to/resource.js"); } ```

  9. Mar 2022
  10. Feb 2022
    1. js queryClient .getQueryCache() .findAll(['partial', 'key']) .forEach(({ queryKey }) => { queryClient.setQueryData(queryKey, newData) })

    1. However there are some restrictions: if you are going to use different URLs for GET/PATCH, for example, you have to use the same key, otherwise, React Query will not be able to match these queries.

      It is ok to use url as key for React query

  11. Jan 2022
    1. Routen, A., O’Mahoney, L., Ayoubkhani, D., Banerjee, A., Brightling, C., Calvert, M., Chaturvedi, N., Diamond, I., Eggo, R., Elliott, P., Evans, R. A., Haroon, S., Herret, E., O’Hara, M. E., Shafran, R., Stanborough, J., Stephenson, T., Sterne, J., Ward, H., & Khunti, K. (2022). Understanding and tracking the impact of long COVID in the United Kingdom. Nature Medicine, 28(1), 11–15. https://doi.org/10.1038/s41591-021-01591-4

    1. In previous technologies, the development for different devises were handled via different teams due to which there were gaps witnessed in the applications.
    1. Instead of render props, we use Svelte's slot props: // React version <Listbox.Button> {({open, disabled} => /* Something using open and disabled */)} </Listbox.Button> <!--- Svelte version ---> <ListboxButton let:open let:disabled> <!--- Something using open and disabled ---> </ListboxButton>
    1. Data Transformation

      […]

      3. using the select option

      v3 introduced built-in selectors, which can also be used to transform data:

      /* select-transformation */
      
      export const useTodosQuery = () =>
        useQuery(['todos'], fetchTodos, {
          select: (data) => data.map((todo) => todo.name.toUpperCase()),
        })
      

      selectors will only be called if data exists, so you don't have to care about undefined here. Selectors like the one above will also run on every render, because the functional identity changes (it's an inline function). If your transformation is expensive, you can memoize it either with useCallback, or by extracting it to a stable function reference:

      /* select-memoizations */
      
      const transformTodoNames = (data: Todos) =>
        data.map((todo) => todo.name.toUpperCase())
      export const useTodosQuery = () =>
        useQuery(['todos'], fetchTodos, {
          // ✅ uses a stable function reference
          select: transformTodoNames,
        })
      
      export const useTodosQuery = () =>
        useQuery(['todos'], fetchTodos, {
          // ✅ memoizes with useCallback
          select: React.useCallback(
            (data: Todos) => data.map((todo) => todo.name.toUpperCase()),
            []
          ),
        })
      

      Further, the select option can also be used to subscribe to only parts of the data. This is what makes this approach truly unique. Consider the following example:

      /* select-partial-subscriptions */
      
      export const useTodosQuery = (select) =>
        useQuery(['todos'], fetchTodos, { select })
      
      export const useTodosCount = () => useTodosQuery((data) => data.length)
      
      export const useTodo = (id) =>
        useTodosQuery((data) =>
          data.find((todo) => todo.id === id))
      

      Here, we've created a useSelector like API by passing a custom selector to our useTodosQuery. The custom hooks still works like before, as select will be undefined if you don't pass it, so the whole state will be returned.

      But if you pass a selector, you are now only subscribed to the result of the selector function. This is quite powerful, because it means that even if we update the name of a todo, our component that only subscribes to the count via useTodosCount will not rerender. The count hasn't changed, so react-query can choose to not inform this observer about the update 🥳 (Please note that this is a bit simplified here and technically not entirely true - I will talk in more detail about render optimizations in Part 3).

      • 🟢 best optimizations
      • 🟢 allows for partial subscriptions
      • 🟡 structure can be different for every observer
      • 🟡 structural sharing is performed twice (I will also talk about this in more detail in Part 3)
    2. Data Transformation

      [...]

      2. In the render function

      As advised in Part 1, if you create custom hooks, you can easily do transformations there:

      /* render-transformation */
      
      const fetchTodos = async (): Promise<Todos> => {
        const response = await axios.get('todos')
        return response.data
      }
      
      export const useTodosQuery = () => {
        const queryInfo = useQuery(['todos'], fetchTodos)
        return {
          ...queryInfo,
          data: queryInfo.data?.map((todo) =>
            todo.name.toUpperCase()),
        }
      }
      

      As it stands, this will not only run every time your fetch function runs, but actually on every render (even those that do not involve data fetching). This is likely not a problem at all, but if it is, you can optimize with useMemo. Be careful to define your dependencies as narrow as possible. data inside the queryInfo will be referentially stable unless something really changed (in which case you want to recompute your transformation), but the queryInfo itself will not. If you add queryInfo as your dependency, the transformation will again run on every render:

      /* useMemo-dependencies */
      
      export const useTodosQuery = () => {
        const queryInfo = useQuery(['todos'], fetchTodos)
        return {
          ...queryInfo,
          // 🚨 don't do this - the useMemo does nothing at all here!
          data: React.useMemo(
            () => queryInfo.data?.map((todo) => todo.name.toUpperCase()),
            [queryInfo]
          ),
          // ✅ correctly memoizes by queryInfo.data
          data: React.useMemo(
            () => queryInfo.data?.map((todo) => todo.name.toUpperCase()),
            [queryInfo.data]
          ),
        }
      }
      

      Especially if you have additional logic in your custom hook to combine with your data transformation, this is a good option. Be aware that data can be potentially undefined, so use optional chaining when working with it.

      • 🟢 optimizable via useMemo
      • 🟡 exact structure cannot be inspected in the devtools
      • 🔴 a bit more convoluted syntax
      • 🔴 data can be potentially undefined
    1. 🤔 So what?

      Let’s review a typical Redux process for a fetch operation:

      1. Dispatch an Action fetchSomething() from within the Component
      2. This Action hits the Reducer which will update the store with something like isLoading: true
      3. The Component re-renders and displays a loader
      4. In the meanwhile the Action hits the Middleware which takes care of calling the API
      5. The API returns the response to the Middleware, which dispatches another Action: fetchSomethingSucceeded() when succeeded, or fetchSomethingFailed() when failed
      6. The succeeded/failed Action hits the Reducer, which updates the store
      7. Finally, the response is back to the Component (optionally through a memoized selector) which will show the data

      It’s a long process for just a simple fetch, isn’t it?

  12. Dec 2021
    1. Increasing StaleTime

      React Query comes with a default staleTime of zero. This means that every query will be immediately considered as stale, which means it will refetch when a new subscriber mounts or when the user refocuses the window. It is aimed to keep your data as up-to-date as necessary.

      This goal overlaps a lot with WebSockets, which update your data in real-time. Why would I need to refetch at all if I just manually invalidated because the server just told me to do so via a dedicated message?

      So if you update all your data via websockets anyways, consider setting a high staleTime. In my example, I just used Infinity. This means the data will be fetched initially via useQuery, and then always come from the cache. Refetching only happens via the explicit query invalidation.

      You can best achieve this by setting global query defaults when creating the QueryClient:

      const queryClient = new QueryClient({
        defaultOptions: {
          queries: {
            staleTime: Infinity,
          },
        },
      })
      
  13. Nov 2021
    1. { target: { value } }

      This might seem confusing at first glance. However this is just simple "nested destructruing" and "smart function parameters" used together

      Read the "Nested Destructuring" and "Smart Function Parameters" sections from the link below to get a better idea of what's going on.

      https://javascript.info/destructuring-assignment#object-destructuring

      the set() function can also be written as -----

      let set = (name) => {
          return ( (e) => {
              setDetails( {...details , [ name ] : e.target.value });
              console.log(details);
          })
      }
      

      notice how the predeclared variable name is being used as a key in the object. { [name] : value } NOT { name : value}. Skipping the box brackets will throw you an error This is because name is actually a variable. Similar to the way in which we use object[key] = value; notation to add a k-v pair, we have to use { [name] : value } ie. enclose the variable name in square brackets while creating an object using object literal syntax to make sure that the code works

  14. Oct 2021
  15. Sep 2021
    1. redux-thunk does: it is a middleware that looks at every action that passes through the system, and if it’s a function, it calls that function.
  16. Aug 2021
    1. All consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes
    1. It's time to put some of these pieces together. We know that: Calling setState() queues a render of that component React recursively renders nested components by default Context providers are given a value by the component that renders them That value normally comes from that parent component's state This means that by default, any state update to a parent component that renders a context provider will cause all of its descendants to re-render anyway, regardless of whether they read the context value or not!.
    2. Immutability and Rerendering 🔗︎

      This section is gold to use as a teaching example

    3. All of these approaches use a comparison technique called "shallow equality". This means checking every individual field in two different objects, and seeing if any of the contents of the objects are a different value. In other words, obj1.a === obj2.a && obj1.b === obj2.b && ......... This is typically a fast process, because === comparisons are very simple for the JS engine to do. So, these three approaches do the equivalent of const shouldRender = !shallowEqual(newProps, prevProps).
    4. When trying to improve software performance in general, there are two basic approaches: 1) do the same work faster, and 2) do less work. Optimizing React rendering is primarily about doing less work by skipping rendering components when appropriate.
    5. After it has collected the render output from the entire component tree, React will diff the new tree of objects (frequently referred to as the "virtual DOM"), and collects a list of all the changes that need to be applied to make the real DOM look like the current desired output. The diffing and calculation process is known as "reconciliation".
    1. Here’s where immutability comes in: if you’re passing props into a PureComponent, you have to make sure that those props are updated in an immutable way. That means, if they’re objects or arrays, you’ve gotta replace the entire value with a new (modified) object or array. Just like with Bob – kill it off and replace it with a clone. If you modify the internals of an object or array – by changing a property, or pushing a new item, or even modifying an item inside an array – then the object or array is referentially equal to its old self, and a PureComponent will not notice that it has changed, and will not re-render. Weird rendering bugs will ensue.
    2. An easy way to optimize a React component for performance is to make it a class, and make it extend React.PureComponent instead of React.Component. This way, the component will only re-render if its state is changed or if its props have changed. It will no longer mindlessly re-render every single time its parent re-renders; it will ONLY re-render if one of its props has changed since the last render.
    1. connect is pure connect automatically makes connected components “pure,” meaning they will only re-render when their props change – a.k.a. when their slice of the Redux state changes. This prevents needless re-renders and keeps your app running fast.
    1. My personal summary is that new context is ready to be used for low frequency unlikely updates (like locale/theme). It's also good to use it in the same way as old context was used. I.e. for static values and then propagate updates through subscriptions. It's not ready to be used as a replacement for all Flux-like state propagation.
    2. One problem with the "Context vs Redux" discussions is that people often actually mean "I'm using useReducer to manage my state, and Context to pass down that value". But, they never state that explicitly - they just say "I'm using Context". That's a common cause of the confusion I see, and it's really unfortunate because it helps perpetuate the idea that Context "manages state"