react & i18next, why do i need react-i18next - reactjs

I am new to i18next and I dont really understand why there is a need to use react-i18next when playing with react.
Using an external library like moment.js in my component i do : const date = moment(this.state.date)
Can I do the something like below with i18next :
import i18next from 'i18next';
const translated = () => (
<h1>{i18next.t('title')}</h1>
)
Thanks

sure you can directly use i18next. react-i18next is only some optimization to use it in react -> eg. rerender on language change, or dynamic load of the namespaces using the hoc or render prop. Or the Trans component which allows you to nest react components into translations. But there is no magic, like there is no magic in jquery-i18next or vue-i18next -> it just simplifies your task.

Related

How to use t function from i18next outside of React Native component?

I try to use t function of i18next outside of React Native component. In some places I need to use "t" in function which is defined not in component. I don't know what would be the best way to pass the "t" into such functions.
Currently I'm thinking of these options:
import "t" from i18n config file on top of the file where I want to use "t"
use hook useTranslation() from 'react-18next' (not sure if this works if we use the hook not in component)
also I can pass "t" as argument to the function , but this could be overcomplicating the function.
What option do you think is the simplest and the best?
So far I use useTranslation hook and sometimes importing "t" from i18n.js config file, but I need to stick to one method of importing "t".
I personally use the first option which works pretty well and don't add complexity to function's parameters
I personally do this inside utils files which do not contains any component:
import { t } from 'i18next';
export async function generateMailBody(user, isContact) {
const yourMessage = isContact ? t('Your_message') : t('Problem_description');
...
}

Import a file as a string (or source asset) in Gatsby / React

I want to import .ts, .tsx, .js, and .jsx files into a react component and render them within a PrismJS highlighting block. For example, let's say I have a TypeScript file with functionA in it that I want to highlight in my actual website:
functionA.ts:
export function functionA() {
console.log("I am function A!");
}
I want to include this in a different component. The problem is, when I import it, I am obviously importing the webpack module version of it. My weak attempt at trying to get my function render in a react component looks like this:
MyComponent.tsx:
import * as React from "react"
import { functionA } from "./functionA"
export function MyComponent() {
return (
<>
<h1>Here is your code block:</h1>
<pre>
<code>
{functionA.toString()}
</code>
</pre>
</>
)
}
and what will actually render on the page where the code block is will look something like this:
Here is your code block:
WEBPACK__IMPORT.functionA() {
console.log("I am function A!")
}
I can't exactly remember what the .toString() function output looked like, but the point is it is NOT just the contents of the file how it appears in a code edit for example - it has been modulized by WebPack.
So, in a Gatsby project, how can i get these various code snippets to be imported directly as a string, purely as they are written, without WebPack enacting its import stuff on it? Is there a plugin or some way to tell Webpack to use the imported file as its asset/source module type? I know for MD or MDX files there is the gatsby-remark-embed-snippet, but I am building a component based HTML page and can't use MD or MDX files!
It's very late, and perhaps I just can't see the forest from the trees, I know there must be a way to do this...
You need to require the file using webpack's raw-loader, i.e:
const functionA = require("!!raw-loader!./functionA");
This works for create-react-app, as in the solution discussed here, and this works for Gatsby as well!
After using require on such a file, the file contents can be rendered in the component as:
<pre>{functionA.default.toString()}</pre>
It's then up to you to add syntax highlighting using a tool like prism or similar.
Note this solution will only work as long as Gatsby V3 continues to use WebPack v4, as raw-loader is deprecated in WebPack v5 and will be phased out for asset/source type modules.

Do you really need to import 'React' when creating hooks? (React-hooks)

I saw the examples where https://reactjs.org/docs/hooks-custom.html they always do:
import React, { useState, useEffect } from 'react';
But React is not really used in the file, do we really need it and why?
I asked this question because I am encountering an issue with eslint saying:
'React' is defined but never used no-unused-vars - And I'm on create-react-app 3.0.1 which eslint is already included - (and I'm not sure how to fix this - already tried this and also tried adding it on package.json eslintConfig but still nothing)
You will need React if you are rendering JSX.
To avoid that eslint warning, you should use react-in-jsx-scope rule from eslint-plugin-react.
In that rule, it also explains why you need React in the file, even if you don't use it (you think you don't use it, but if you render JSX, you do).
When using JSX, <a /> expands to React.createElement("a"). Therefore the React variable must be in scope.
If you are using the #jsx pragma this rule will check the designated variable and not the React one.
React 17 has a new JSX transform which no longer requires the import (also backported to new versions 16.14.0, 15.7.0, and 0.14.10). You can read more about it here:
https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html
// no import needed
const App = () => <div>hello!</div>
However, you still need to import to use hooks:
import { useState } from 'react'
const App = () => {
const [stuff, setStuff] = useState('stuff')
return <div>{stuff}</div>
}
The docs also link to a script to automatically update all of the files in a project to fix all of the imports. Personally, I was in the habit of just using the React.useWhatever form so I never needed to mess with the import statement, but using named imports can potentially reduce the final bundle size.
The docs say the named import is now the recommended way, so this is NOT recommended, but if you really want to keep the React import, you can set the below eslint rule to stop it from complaining. Note that this will continue to require it in all files.
"react/jsx-uses-react": "error"
From the React official docs:
Fundamentally, JSX just provides syntactic sugar for the
React.createElement(component, props, ...children) function. The JSX
code:
<MyButton color="blue" shadowSize={2}>Click Me</MyButton>
compiles
into:
React.createElement(MyButton, {color: 'blue', shadowSize: 2},'Click Me' )
You can also use the self-closing form of the tag if
there are no children. So:
<div className="sidebar" />
compiles into:
React.createElement('div', {className: 'sidebar'}, null )
https://reactjs.org/docs/jsx-in-depth.html
EDIT Hooks are also under the React namespace, React.useState ...etc

3d.io api at React project

Does 3d.io support React components at future ? Now, I need to find dom element utilized "ref" from component to retrieve io3d objects.
render () {
// this.props.elements is the state from getAframeElements
if (this.props.sceneId !== '') {
this.props.elements.forEach( (item) => {
this.refs.scene.appendChild(item)
})
}
return (
<a-entity ref="scene">
</a-entity>
)
}
Do you have any guides how to use 3d.io at React project ? Or I need to use document.querySelector after componentDidMount event at React.
A few things here:
How to use react and 3d.io
Most 3dio-js methods return plain js objects and arrays that you can use with any javascript library.
Here's how you could use io3d.furniture.search in a react component: https://jsfiddle.net/wo2xpb9g/
How to combine react and a-frame
There is the aframe-react project that will make combining a-frame and react easier https://github.com/ngokevin/aframe-react
As of newer versions of react it seems possible to combine a-frame and react directly like you've done, here's an example: https://codepen.io/cassiecodes/pen/akXWjo?editors=1010
How to use io3d.scene.getAframeElements with react
getAframeElements is a convenience method which converts sceneStructure into real a-frame DOM nodes. In react projects, real DOM nodes are generated by react itself.
There are two possibilities,
Instead of getAframeElements, convert sceneStructure from io3d.scene.getStructure into react virtual DOM yourself. Hopefully a community library will be published for this soon.
Keep the a-frame DOM separate from react. This is the approach sometimes used to combine react with libraries such as D3, which directly manipulate the DOM... that approach is discussed with examples here: https://medium.com/#Elijah_Meeks/interactive-applications-with-react-d3-f76f7b3ebc71

Reagent generate a React Component that passes React.isValidClass(component)?

I'm trying to use react-router in my Clojurescript Reagent project. The problem is, react-router requires that components pass React.isValidClass(component), which in React 0.11.2 is defined as:
ReactDescriptor.isValidFactory = function(factory) {
return typeof factory === 'function' &&
factory.prototype instanceof ReactDescriptor;
};
Reagent seems to generate components as an object instead of a function. Here is my code:
(defn home []
[:div [:h1 "Home Page placeholder"]])
(reagent/as-component (home)) ; => #<[object Object]>
Has anyone worked out how to make this sort of interop work?
What reagent-react-router does to make this work is use reagent.core/reactify-component. The reactify-component exists to make Reagent components valid React components for these kinds of inter-op scenarios.

Resources