WebStorm functional snippet React - reactjs

Does anybody knows what the shortcut is for React functional components snippet in WebStorm?
So far I only found shortcut for class components.

Please try rsf - it creates a code like
import React from 'react';
function Func(props) {
return (<div></div>);
}
export default Func;

I use the rsc live template a lot for new components.
This creates code like:
import React from 'react';
const MyComponent = () => {
return (
<div>
</div>
);
};
export default MyComponent;
Apart from that I created my own live template in the JavaScript category for creating arrow functions to save even more time, which creates code like:
const myFunction = () => {
};
Just add a new Live Template under the JavaScript category with this template text:
const $1$ = () => {
$END$
};
And make sure to set applicable in to JavaScript and TypeScript and select the checkboxes for:
statement
top level statement

i. rsf - Creates a stateless React component as a named function without PropTypes.
import React from 'react';
function AppComponent(props) {
return (
<div></div>
);
}
export default AppComponent;
ii. rsfp - Creates a stateless React component as a named function with PropTypes.
import React from 'react';
import PropTypes from 'prop-types';
AppComponent.propTypes = {
};
function AppComponent(props) {
return (
<div></div>
);
}
export default AppComponent;

You can configure your own templates in the web-storm by your own key word
go to settings -> editor -> live templates
Selecting React, on the right side press the add button or alt + insert to create a new template key bindings are based on Linux system
Click Live template it will open a pane on below
Add your desired abbreviation in my case i wanted a arrow function with export so i added rafce, description is optional
In the live template paste your desired format of code generation for your abbreviation
Example:
// Created on $DATE$ by $USER$: for project $project$
import React from 'react'
const $FileName$ = () => {
return (
<div>$FileName$</div>
)
}
export default $FileName$
${var_name}$ can be used to describe a inbuilt function on the ide or your custom variable
for more reference refer the webstorm documentation on inbuilt functions for live templates webstorm live templates
You can edit these variable declarations on edit variables to get your desired behavior
Variable declaration for above template
Set the application context to java script and type script click save and apply your template is ready

Related

How should I improve this behavior in React?

in my company we are using ReactJS to develop our website. We also have legacy code in jQuery (I know, we are trying to change everything to React). My problem is that we have some global functions that we have to pass throughout all the component tree. For instance, we have a control function that we have to pass throughout 8 components, but only the last one actually calls it.
So, I wonder if there's a way to avoid this problem. Another problem is that we have several react trees on the page, because as I said, we have some legacy code in jQuery. Any ideas/suggestions?
(pls if this question does not belong in this forum let me know)
So you have to create yout context like this:
import React from "react";
const YourContext = React.createContext({ func: null });
export default YourContext ;
then in your parent component you can initialize it and make it available in child components:
import React from "react";
import YourContext from "./YourContext";
const YourParentComponent = () => (
<YourContext.Provider value={{ func: () => {} }}>
....
</YourContext.Provider>
);
and in your child components you can use it:
import React, { useContext } from "react";
import YourContext from "../YourContext";
const YourChildComponent = () => {
const { func } = useContext(YourContext);
Have a look at React Context, it will allow you to pass data through the components tree without passing down the props.

How to use dynamic import with a named export in Next.js?

I have this react component. It works just fine for me.
import { Widget } from 'rasa-webchat';
function CustomWidget(){
return (
<Widget
initPayload={"payload"}
socketPath={"/socket.io/"}
customData={{"language": "en"}}
/>
)
}
export default CustomWidget;
But when I try to use it on my next.js website it fails to work.
It gives me a window is not defined error.
I think I resolved this particular error by using the dynamic importer:
import dynamic from "next/dynamic";
const webchat = dynamic(
() => {
return import('rasa-webchat');
},
{ ssr: false }
);
But now I can't figure out how to actually use the widget component from the package.
Am I allowed to import { Widget } from 'rasa-webchat' or is this just not compatible with next.js for some reason? If it's possible, how do I do it?
The syntax for named exports is slightly different. You can use the widget with a dynamic import as follows:
import dynamic from 'next/dynamic';
const Widget = dynamic(
() => import('rasa-webchat').then((mod) => mod.Widget),
{ ssr: false }
);
function CustomWidget(){
return (
<Widget
initPayload={"payload"}
socketPath={"/socket.io/"}
customData={{"language": "en"}}
/>
)
}
export default CustomWidget;
For further details check Next.js dynamic import documentation.
Nextjs is a frame work that allows you to build Static and Server Side rendered apps. So, it uses Nodesj under hood and window is not defined in nodejs. Only way to accessing window in react ssr frameworks is useEffect hook. Your dynamic import solution is right , becuase you are getting file on client side. I hope it makes sense.
Have a great day

How do I use getElementsByClassName when I'm using CSS modules in React.js?

I want to apply getElementsByClassName to a element with dynamic name assigned by CSS modules in React.js. For example, if I named a class as 'firstLink' using className={styles.firstLink} in a file named RegisterPage.js, the resulting name for the class is:
The __1Ozd bit is random. How can I apply getElementsByClassName in this situation ?
CSS modules provides key-value object which you can use in the code.
Key is class name defined by you, value is generated class name.
import React from 'react'
import style from './style.module.css'
export default function Component() {
React.useEffect(() => {
console.log(document.getElementsByClassName(style.firstLink))
}, [])
return <div className={style.firstLink} />
}
And I believe there can't be any reason to use vanilla js functions like getElementsByClassName, using state and in some cases using refs should cover all cases, example:
import React from 'react'
export default function Component() {
const ref = React.useRef()
React.useEffect(() => {
console.log(ref.current) // Will output dom element
}, [])
return <div ref={ref} />
}
After some thinking, perhaps there are old-school libraries which can accept root element only by class name.
In react, behaviors such as you wanted is termed Refs, see this.
If you are building functional component do this:
const {useRef} = React
const Component =>{
styelRef = useRef()
//refer to your anchor tag style here which should be called className
const styleFnc=()=>{
styleRef.current.className = "__1Ozd"
}
return(
<a ref={styleRef} href="...." className={`RegisterPage_firstLink${styelFnc}`}></a>
)
}

React Developer Tools shows all components as "Anonymous"

I've installed the React Developer Tools extension on Google Chrome to debug a React application written in TypeScript, but once I start debugging the application and open the "Components" window, all components are shown as "Anonymous".
Granted, the application uses mostly function components.
Does anyone know if there is a way to get React Developer Tools to show component names in its component tree?
This happens when you define your components like so:
// Default arrow function export
export default () => {
// ...
}
// Default function export
export default function() {
// ...
}
You can replace with the following to fix the issue:
const CustomComponent = () => {
// ...
}
export default CustomComponent;
// or
export default function YourComponent() {
// ...
}
If you're using an exported anonymous functional component or a memo'ed component; it would be shown as Anonymous
Refer this - https://github.com/facebook/react/issues/17876
Or try solutions mentioned here - React Dev tools show my Component as Unknown

How to render a reactjs component stored in a redux reducer?

I have a redux reducer loaded with several reactjs components.
I want to load these inside other components through this.props
Like: this.props.components.MyReactComponent
class OtherComponent extends Component {
render() {
const Component = this.props.components.MyReactComponent
return (
<div>
<Component />
</div>
)
}
}
Is this possible? If so, how?
EDIT The component is a connected component. I am able to load it but it is broken. In this case, it is a counter, when you click to increment or decrement nothing happens. In the console, there is this error:
Uncaught ReferenceError: _classCallCheck is not defined
if I convert the component into a dumb component (without connecting it), the error is this:
Uncaught ReferenceError: _classCallCheck3 is not defined
EDIT 2
I found out why those errors show up. It is because the react component gets stripped out when stored in the reducer:
A react component would look something like this:
{ function:
{ [Function: Connect]
displayName: 'Connect(Counter)',
WrappedComponent: { [Function: Counter] propTypes: [Object] },
contextTypes: { store: [Object] },
propTypes: { store: [Object] } } }
However, after I store it inside a reducer, it loses its properties and ends up looking something like this:
{ function:
{ [Function: Connect] } }
After reading the comments below, I thought of an alternative. I can store in a reducer the path to each component, then make a new wrapper component that could render those other components from those paths.
I tried it but encoutered a different problem with the funcion require from nodejs that for some weird reason is not letting me user a variable as an argument. For example:
This works:
var SomeContent = require('../extensions/myContent/containers')
This does not:
var testpath = '../extensions/myContent/containers'
var SomeContent = require(testpath)
Giving me the following error:
Uncaught Error: Cannot find module '../extensions/myContent/containers'.
It is adding a period at the end of the path. How can I prevent require to add that period?
If you can think of any other alternative I can implement for what I am trying to do, I would greatly appreciate it.
EDIT 3 Following Thomas advice...
What I am trying to accomplish is this:
I want to be able to render react components inside other react components, I know how to do it the same way most us know how to; however, I want to be able to do it by importing a file that would contain all the components without actually having to import and export each one of them:
OtherComponent.js
import React, { Component } from 'react'
import { SomeComponent } from '../allComponentes/index.js'
export default class OtherComponent extends Component {
render() {
return (
<SomeComponent />
)
}
}
SomeComponent.js
import React, { Component } from 'react'
export default class SomeComponent extends Component {
render() {
return (
<div>
Hello
</div>
)
}
}
allComponents/index.js
import SomeComponent from '../allComponents/SomeComponent/index.js'
export { SomeComponent }
What I am trying to do in allComponents/index.js is to avoid having import/export statements for each component by reading (with fs module) all the components inside the allComponents folder and export them.
allComponents/index.js (pseudocode)
get all folders inside allComponents folder
loop through each folder and require the components
store each component inside an object
export object
When I tried that, I encountered multiple issues, for one, export statements have to be in the top-level, and second, fs would work only on the server side.
So, that is why I thought of loading all the components in a reducer and then pass them as props. But as I found out, they got stripped out when stored them in a reducer.
Then, I thought of only storing the path to those components inside a reducer and have a wrapper component that would use that path to require the needed component. This method almost worked out but the nodejs function require wont allow me to pass a variable as an argument (as shown in EDIT 2)
I think your question is not really to do with redux but rather is (as you say):
What I am trying to do in allComponents/index.js is to avoid having import/export statements for each component by reading (with fs module) all the components inside the allComponents folder and export them.
By way of example, I have all of my (dumb) form components in a folder path components/form-components and the index.js looks something like:
export FieldSet from './FieldSet'
export Input from './Input'
export Label from './Label'
export Submit from './Submit'
export Select from './Select'
export Textarea from './Textarea'
Then when I want to import a component elsewhere, it is import { FieldSet, Label, Input, Submit } from '../../components/form-components/';

Resources