Home > Mobile >  Passing arguments to the elements between tags
Passing arguments to the elements between tags

Time:12-28

the variable marked in the image is coming from the Formik Component what is the name of this approach of passing an argument to the elements inside the tags (that's why the title is not clear so much, due to the limitation of knowing the name of the approach), and would appreciate an example of it.

screenshot JSX structure

CodePudding user response:

I use this pattern in my app, check it out:

import React, { useCallback, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { getGeo } from '@/data/geoLocation/useGeoLocation';
import { GeoLocation } from 'types/GeoLocation';

interface ChildrenParams {
  currentLanguage: string;
  handleChangeLanguage: (lang: string, cb?: () => void) => void;
  languages: string[];
}

export default function LocaleToggle({
  children,
}: {
  children: (params: ChildrenParams) => JSX.Element;
}): JSX.Element {
  const { i18n } = useTranslation();

  const languages: string[] = React.useMemo(
    () => Object.keys(i18n.services.resourceStore.data),
    [i18n],
  );

  // Set stored language on mount.
  useEffect(() => {
    const region = i18n.language;
    if (!languages.includes(region)) {
      getGeo().then((ip: GeoLocation) => i18n.changeLanguage(ip.country_code));
      return;
    }
    i18n.changeLanguage(region.toLowerCase());
  }, [i18n, languages]);

  const handleChangeLanguage = useCallback(
    (lang: string, cb?: () => void) => {
      i18n.changeLanguage(lang.toLocaleLowerCase());
      if (cb) cb();
    },
    [i18n],
  );

  return (
    <>
      {children({
        currentLanguage: i18n.resolvedLanguage,
        handleChangeLanguage,
        languages,
      })}
    </>
  );
}

Then, I can use it like this, in the formik way:

  <LocaleToggle>
    {({ languages }) => (
      <Select onChange={handleChangeLanguageSelect} value={newLang}>
        {languages.map((l) => (
          <option key={l} value={l}>
            {getLanguage(l)}
          </option>
        ))}
      </Select>
    )}
  </LocaleToggle>

I'm not sure about how this is called, but I think it's named 'render prop pattern'

CodePudding user response:

The JSX documentation calls this functions as children:

Functions as Children

Normally, JavaScript expressions inserted in JSX will evaluate to a string, a React element, or a list of those things. However, props.children works just like any other prop in that it can pass any sort of data, not just the sorts that React knows how to render. For example, if you have a custom component, you could have it take a callback as props.children:

// Calls the children callback numTimes to produce a repeated component
function Repeat(props) {
  let items = [];
  for (let i = 0; i < props.numTimes; i  ) {
    items.push(props.children(i));
  }
  return <div>{items}</div>;
}

function ListOfTenThings() {
  return (
    <Repeat numTimes={10}>
      {(index) => <div key={index}>This is item {index} in the list</div>}
    </Repeat>
  );
}

Children passed to a custom component can be anything, as long as that component transforms them into something React can understand before rendering. This usage is not common, but it works if you want to stretch what JSX is capable of.

// Calls the children callback numTimes to produce a repeated component
function Repeat(props) {
  let items = [];
  for (let i = 0; i < props.numTimes; i  ) {
    items.push(props.children(i));
  }
  return <div>{items}</div>;
}

function ListOfTenThings() {
  return (
    <Repeat numTimes={10}>
      {(index) => <div key={index}>This is item {index} in the list</div>}
    </Repeat>
  );
}

ReactDOM.createRoot(document.querySelector("#root")).render(<ListOfTenThings />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

  • Related