How to use Ziggy with React and Inertia - reactjs

How can I call in a React component the JavaScript route function generated by the Ziggy's #route directive ?
The route function is generated at runtime so it's impossible to import it beforehand in the react component and therefore, Laravel Mix throws an error and can't compile the project. To be clearer, since i'm using Typescript, I can't compile my component without importing the route function somehow.
My stack is Laravel 8, Inertia, React.

I encountered the same problem and here is my solution to use ziggy-js in typescript.
import route from 'ziggy-js'
install #types/ziggy-js as you're using typescript with npm install --save-dev #types/ziggy-js

In your app.blade.php make sure to pass #route as it is in the head section.
ie:
`
some links here
#route --> pass it here
`
then you can access it in your component:
1-import route from "ziggy-js";
2-import { InertiaLink } from "#inertiajs/inertia-react";
<InertiaLinkhref={route("your_route_name", { key: value }).url()}>View</InertiaLink>
Let me know if that helps you out.

Related

Use styled-jsx without ejecting create-react-app

Since I started using NextJS, I've grown quite fond of styled-jsx (I know, not everyone likes it). I'd love to use it in my create react app. Locally it works great. However, react shows me the error:
Warning: Received `true` for a non-boolean attribute `jsx`.
To my understanding, this means that the code does not get transpired by babel. I would need to add the babel plugin to my Create React App Babel config - which isn't possible without ejecting.
I've also read about react-app-rewired but I don't trust it enough to put into production. Is there a more native way to use styled-jsx in my create react app project?
I just happened to answer this in details under another question :) Hope it helps
https://stackoverflow.com/a/66285652/511908
According to the styled-jsx docs, it can be used in create-react-app by using the css.resolve function provided in styled-jsx/macro. Read about it here.
I think this is the intended use but I could not get it working:
import css from "styled-jsx/macro";
export function Login() {
const { demoClass, styles } = css.resolve`
label {
color: green;
}
`;
return (
<label className={demoClass}>Test</label>
);
}
Even if this did work, I dislike it and would rather use styled components or CSS modules (built into CRA, by the way). This is nowhere near as clean as the normal styled-jsx code.
It seems that styled-jsx just does not work well with CRA without ejecting. If you do get it working please let me know, but right now I am going down the CSS modules with Styled Components route.

requestAnimationFrame is not defined it Next.js with React Native Web (Animated module)

I'm working on Next.js and React-Native-Web. I managed to run them together following the official Next.js example but when I'm trying to use the Animated package from the react-native it fails with Error that the requestAnimationFrame isn't defined. Basically this functionality does the node_modules package but I set the alias in webpack to translate all react-native requires to the react-native-web so even the node_modules package should use the react-native-web.
Any suggestions on how to solve it?
ReferenceError: requestAnimationFrame is not defined
at start (...node_modules\react-native-web\
dist\cjs\vendor\react-native\Animated\animations\TimingAnimation.js:104:11)
enter code here
Thanks for any help!
The problem is in the missed RequestAnimationFrame functionality at the server. This error happens when Next.js tries to render the component during SSR.
Unfortunately, there is no polyfill, etc. for such purpose so I just decided to use the Next.js dynamic imports for a Component that has animation functionality.
Next.js Official documentation
My own case оust to show how code looks:
import dynamic from 'next/dynamic';
const AutocompleteDropdown = dynamic(
() => import(
'myAwesomeLib/components/dropdown/autocomplete/AutocompleteDropdown'
),
{
ssr: false,
}
);
Now you can use the AutocompleteDropdown as the standard JSX component
I'm coding an App with React Native Web and NextJS 12, and in 2021 I encounter this problem and I fixed it, but now I know my fix was only for Next Dev, because it returned for Next Production Build.
Solution details:
No Dynamic import (which is useful too, but can be annoying when having lot of components using it)
Using RAF polyfill and Webpack ProvidePlugin.
Main thing to have in mind is that next.config.js with webpack 5 is going to check the codes first before even reach next entry points _documents.js and _app.js. It means that, you can put polyfill in those entry point files, it will still raise error of RAF undefined. You have to make requestAnimationFrame ready for config check.
DEV approach that will work on Next DEV only. Install RAF package https://www.npmjs.com/package/raf and In next.config.js add codes:
const raf = require('raf');
raf.polyfill();
This will add requestAnimationFrame and cancelAnimationFrame function to global and window object if they don't have it. In our case, it would add it in global for NodeJS.
But this solution won't work when executing npm run dev. I don't know why, if anyone knows why Next or Webpack 5 act differently from DEV to PRODUCTION, let me know.
Complete Solution:
Use ProvidePlugin config of webpack 5 https://webpack.js.org/plugins/provide-plugin/ . Create a file to use as modules, let's say: raf.js in root project or anywhere you want:
const raf = require('raf');
const polys = {};
raf.polyfill(polys);
module.exports = polys.requestAnimationFrame;
And in next.config.js use it inside webpack: () = {} like:
webpack: (config, options) => {
// console.log('fallback', config.resolve.fallback);
if (options.isServer) {
// provide plugin
config.plugins.push(
new options.webpack.ProvidePlugin({
requestAnimationFrame: path.resolve(__dirname, './raf.js'),
}),
);
}
And now, it's up to you to adapt to your existing config logic. By doing this, in Production Build, NextJS is injecting the requestAnimationFrame function in Server Side everywhere a module is using it.

How to integrate whatwg-fetch in Gatsby

Does anyone know how to integrate the whatwg-fetch fetch polyfill in gatsby?
What I have done so far is import 'whatwg-fetch'; in the gatsby-browser.js. Now I'm not sure how to add it as a first element in the webpack's entry property presumably in the gatsby-node.js.
Yes, here is a copy of my (tested and working) gatsby-browser.js:
import 'whatwg-fetch' // require('whatwg-fetch') // if it's gatsby v2 - https://gatsby.app/no-mixed-modules
exports.onClientEntry = () => {
// Don't need to do anything here, but if you don't
// export something, the import won't work.
}
No need to add whatwg-fetch to webpack's entry property in gatsby-node.js.
Also whatwg-fetch depends on Promises, but Promise is already polyfilled in gatsby, so no need to add an extra polyfill for Promise.

Is there any difference between React.render() and ReactDOM.render()?

I have noticed that some of the places in articles they have used React.render() and some of the places ReactDOM.render(). Is there any specific difference between these two?
This is a very recent change introduced with 0.14. They split up React into a core library and the DOM adapter. Rendering is now done via ReactDOM.render.
https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html
React.render has been deprecated as of React 0.14. With packages like react-native, react-art, react-canvas, and react-three, it is clear that the beauty and essence of React has nothing to do with browsers or the DOM.
To make this more clear and to make it easier to build more environments that React can render to, the main react package has been split into two: react and react-dom.
This paves the way to writing components that can be shared between the web version of React and React Native.
The react package contains React.createElement, .createClass, .Component, .PropTypes, .Children, and the other helpers related to elements and component classes. Think of these as the isomorphic or universal helpers that you need to build components.
The react-dom package has ReactDOM.render, .unmountComponentAtNode, and .findDOMNode.
React.render has been deprecated since React 0.14. React diverged into two separate libraries. The core library knows how to work with React components, nest them together and so on, but to take the component and render it to the DOM is a separate library called ReactDOM. So to render a component, you don't use React you use ReactDOM.
import React from 'react';
import ReactDOM from 'react-dom';
Then you would apply it like so:
ReactDOM.render(App);
If you try to run it like that, back then you would probably have gotten an error that says:
Invalid component element. Instead of passing a component class, make sure to instantiate it by passing it to React.createElement.
If you get that error, it's a bit cryptic, think of the following function below is creating an instance of a component to the DOM:
const App = function() {
return <div>Howdy!</div>;
}
I passed App as a class to ReactDOM.render() and not an instance of the component. So it's saying please ensure you make an instance of the component and then pass it, or we need to instantiate it and then pass it to the DOM.
So you would fix it by passing an instance like so:
ReactDOM.render(<App />);
So that would create an instance of App and pass it to ReactDOM.render() but you would not be quite there yet as you would probably have gotten the following error message:
Target container is not a DOM element.
So React is saying I am trying to render this but I don't know where to render it to because ReactDOM takes a second argument which is a reference to an existing DOM node on the page. When you render this <App /> component, insert that HTML into this element that already exists in our HTML document. You would go to your index.html file and find the div with class="container" or whatever it is and that is the root node. All we have to do is pass a reference to that container like so:
ReactDOM.render(<App />, document.querySelector('.container'));
Then you will get the component rendering to the screen. And lastly, five years ago we got ES6 syntax so that App component from above could be rewritten like so:
const App = () => {
return <div>Howdy!</div>;
}
So using a fat arrow like that is identical to using the function keyword.

localization in react.js suggestions and example

We're on the decision on where to go on localization in react.js, surely there are ways to doing localization, but what would be your recommendation?
I tried yahoo's react-intl but to no avail:
var ReactIntl = require('react-intl') // we did npm install react-intl
// somewhere in the react component
render: function() {
return (<div><ReactIntl.Number>{600}</ReactIntl.Number></div>);
}
gives the error: Cannot read property '_mockedReactClassConstructor' of undefined
spent few hours try to resolve this error, still can't resolve -> give up
I tried l20n by mozilla but not sure if it'll work with react.js
wondering what would you suggest for react.js localization, thanks!
in response to my question. we decided not to use yahoo's react-intl but use i18next instead. Considering using something more stable and popular for our production is important.
what you can do is to initialize i18next at the root of your page, and pass that down through props. Do use a state to prevent page rendering before i18next is initialized.
there is now react-i18next https://github.com/i18next/react-i18next works with i18next >=2.0.0
it's been couple month from now. Perhaps there are more localisation modules out there. But if you wish to do something simple and bypass using so many modules (we only use essential modules lessen the load), here's the setup:
let's say we have a root page and login page (on our router setup, things are based on root page)
root
have a state called i18n (in getInitialState)
detect your language and init the i18n
set the object to i18n state
in render() use something like this
render: function() {
var route;
if (this.state.configLoaded && this.state.i18n) {
route = (
<RouteHandler i18n={this.state.i18n} onLanguageChange={this._languageChangedHandler} />
);
}
return (
<div>
<Loading />
{route}
</div>
);
}
and you pass i18n down through props. or if you wish, using mixins.
login
this.props.i18n.t('...')
I think maybe use FormattedNumber from React-Intl for your purpose.
Things to consider, if you use i18next that only gives you translations , not Times/Dates/Currency etc, you'll need additional libraries like Moment.js. React-Intl gives you it all.
Watch out for IE<9 , you'll have to have the Intl.js polyfill or polyfill service (https://cdn.polyfill.io/v2/docs/). I have found webpack to be problematic loading this polyfill.
Finally , with React-Router latest version see https://github.com/rackt/react-router/blob/master/UPGRADE_GUIDE.md
You'll probably find the section on RouteHandler worthwhile, use
{React.cloneElement(this.props.children, {someExtraProp: something })}
To pass your loacles/messages into views.
Hope that helps

Resources