#javascript #reactjs #locale #globalization
Вопрос:
Разработчики дают мне заголовки таблицы:
const CustomersTable = () =gt; { var headers=lt;gt; lt;thgt;Namelt;/thgt; lt;thgt;Agelt;/thgt; lt;thgt;Another textlt;/thgt; lt;/gt; return lt;Table headers={headers} /gt; }
И это код Table
компонента:
const Table = ({headers}) =gt; { var clonedHeaders = React.Children .toArray(headers.props.children) .map(header =gt; React.cloneElement(header, { className: "text-gray-900 py-3 font-light text-xs" })); return lt;tablegt; lt;theadgt; lt;trgt; {clonedHeaders} lt;/trgt; lt;/theadgt; lt;/tablegt; }
Я могу использовать React.cloneElement
для добавления атрибутов к элементам, которые я получаю в качестве реквизитов моего компонента.
Однако я также хочу иметь возможность изменять текстовое содержимое этих полученных элементов.
Например, я хочу автоматически вызвать функцию перевода локали для элементов заголовка таблицы. Прямо сейчас, если разработчики хотят сделать свои таблицы многоязычными, они должны написать это:
var headers = lt;gt; lt;thgt;{t('Name')}lt;/thgt; lt;thgt;{t('Age')}lt;/thgt; lt;thgt;{t('Other text')}lt;/thgt; lt;/gt;
Я хочу централизовать эту функцию для всех пользователей. t(text)
headers
Могу я это сделать?
Ответ №1:
Вы можете использовать ту же технику для дочерних элементов заголовков, что и для самих заголовков:
const clonedHeaders = React.Children .toArray(headers.props.children) .map(header =gt; React.cloneElement(header, { className: "text-gray-900 py-3 font-light text-xs", children: React.Children.toArray(header.props.children).map(child =gt; { return typeof child === "string" ? t(child) : child; }) }));
Живой Пример:
const {useState} = React; function t(english) { // Just so we can see that it happens return english.toLocaleUpperCase(); } const CustomersTable = () =gt; { var headers=lt;React.Fragmentgt; lt;thgt;Namelt;/thgt; lt;thgt;Agelt;/thgt; lt;thgt;Another textlt;/thgt; lt;/React.Fragmentgt;; return lt;Table headers={headers} /gt;; }; const Table = ({headers}) =gt; { const clonedHeaders = React.Children .toArray(headers.props.children) .map(header =gt; React.cloneElement(header, { className: "text-gray-900 py-3 font-light text-xs", children: React.Children.toArray(header.props.children).map(child =gt; { return typeof child === "string" ? t(child) : child; }) })); return lt;tablegt; lt;theadgt; lt;trgt; {clonedHeaders} lt;/trgt; lt;/theadgt; lt;/tablegt;; }; ReactDOM.render(lt;CustomersTable /gt;, document.getElementById("root"));
lt;div id="root"gt;lt;/divgt; lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"gt;lt;/scriptgt; lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"gt;lt;/scriptgt;
Этот пример не выполняет никакой рекурсии, поэтому он не будет обрабатываться lt;thgt;lt;span className="something"gt;Namelt;/spangt;lt;/thgt;
. Если вы хотите справиться с этим, вам придется написать рекурсивную функцию, чтобы справиться с этим, но это будет в том же духе.
Комментарии:
1. Это был один из самых приятных ответов, которые я видел в своей жизни. Легко и очень практично. Мне удалось глобализировать заголовки более чем 100 таблиц за 5 минут, а не за недели. Огромное спасибо.