loading css/javascript file based on prop - javascript

I am working a reactjs file that uses the react-ace library. Currently my code looks like this
import React, { Component } from 'react';
import 'brace/mode/html';
import 'brace/theme/monokai';
import AceEditor from 'react-ace';
class AceHTML extends Component {
render () {
return (
<AceEditor
mode="html"
theme="monokai"
name="Sample"
showPrintMargin={false}
wrapEnabled={true}
value={this.state.value}
editorProps={{
$blockScrolling: true
}} />
);
}
}
However I am trying to figure out a way to make it more generic. So I could say something like <Ace mode="javascript" /> and then in the component would import brace/mode/javascript instead of brace/mode/html
So my question is: What is the best way to load a library instead of using import?
PS: The reason I specifically pointed out that I am using react is because I am using create-react-app to create the application.

import all assets you want to use and you will be able to make changes as you please.
If you don't want to import all assets initially, you can use dynamic imports and load required chunks when a user requests a different editor configuration:
async changeTheme(theme) {
await import("brace/theme/" + theme)
this.setState({ theme });
}
async changeMode(mode) {
await import("brace/mode/" + mode)
this.setState({ mode });
}
live demo:
https://stackblitz.com/edit/react-nzivmp?file=index.js (without dynamic imports since they don't work on stackblitz)
import React from 'react';
import { render } from 'react-dom';
import brace from 'brace';
import AceEditor from 'react-ace';
import 'brace/mode/html';
import 'brace/mode/javascript';
import 'brace/theme/monokai';
import 'brace/theme/github';
function onChange(newValue) {
console.log('change',newValue);
}
// Render editor
export default ({mode, theme}) => (
<AceEditor
mode={mode}
theme={theme}
onChange={onChange}
name="UNIQUE_ID_OF_DIV"
editorProps={{$blockScrolling: true}}
/>
);

Importing libs isn't job for React. Webpack decides what to load to a bundle file. If you want to use any options based on props you'll need to import both anyway.
If there are large files and you don't want to load both of them for your application's user you can fetch them via AJAX request.

Related

Component Palette Custom Hook

I am fairly new to React and still wrapping my head around custom-hooks. I cam across a code where a custom hook was created to handle the component imports.
useComponentPalette.js
import {TodoEditor} from './components/TodoEditor'
import {TodoItem} from './components/TodoItem'
import {TodoList} from './components/TodoList'
import {CheckBox} from './components/CheckBox'
const defaultComponents = {
TodoEditor,
TodoItem,
TodoList,
CheckBox
}
export function useComponentPalette(){
return defaultComponents
}
And then in order to use the hook,
const {TodoItem, TodoList, Checkbox } = useComponentPalette()
My Question :- Does this approach provides any advantage over the regular imports in the component ? or this is an anti-pattern ?
How I usually import the components is as follows
import {TodoEditor} from './components/TodoEditor'
import {TodoItem} from './components/TodoItem'
import {TodoList} from './components/TodoList'
import {CheckBox} from './components/CheckBox'
function App(){
return(
<>
<TodoList/>
</>
)
}
It's not a good idea to use react hooks like this you can get the same result without react hook
// first file name.js
import {TodoEditor} from './components/TodoEditor'
import {TodoItem} from './components/TodoItem'
import {TodoList} from './components/TodoList'
import {CheckBox} from './components/CheckBox'
export default {
TodoEditor,
TodoItem,
TodoList,
CheckBox
}
//component file
import * as Component form 'first file name';
//<Component.TodoEditor/>
//or
import {TodoEditor} form 'first file name';
The way that I use react-hooks is for making my code more dry and increase it's readability, so react-hooks is not good fit for this kind of usage.
Hi #Sachin,
In my option, React JS use hook to manage reuse stateful logic between components. In other word, Hooks do well to encapsulating state and share logic. If you want to do some stateful logic or condition base logic with these components, then it's fine with that. But if you are using just without condition in the given components. Then, This Is useless for making the custom hook. You can do that without a custom hook in a simpler way.
Here is a simple way to do that:-
In components folder. I create index file, this is the entry point of all my exporting components
In that file. I export all my components, as you can see.
I use that components like this. It much better way. In my option.
import { Header, Footer, Sider } from "./components"
before using react custom hooks, we should be aware of the rationale behind it.
Customs hooks functionality was provided to reuse stateful logic. If logic doesn't require any state, we will use simple functions and if it is about components only there there are different patterns for making code general and scaleable.
So, there is no usage of custom hook in above case at all. For me, I would go with the following code for above scenario:
// components/index.tsx
import {Todo} from './todo'
import {CheckBox} from './components/CheckBox'
export {
Todo,
CheckBox
}
// componentns/todo/index.tsx
import {Editor} from './Editor'
import {Item} from './Item'
import {List} from './List'
const Todo = {
Editor,
Item,
List
}
export default Todo;
and usage will be like
import { Checkbox, Todo } from "components"
...
<Checkbox ... />
<Todo.List ...>
<Todo.Item ... >
</Todo.Editor ... />
</Todo.Item ... >
</Todo.List>
...
P.S Usage can be different based upon the logic of components, just giving an hint how we can patterns to serve our purpose.
Hope it helps.

`npm init react-app` leads to `'React' is not defined no-undef` when changing function component to class component

I used npm init react-app appname which creates, among other files, App.js. In that file is a function component:
function App() {
return (
<SomeJSX />
);
}
I edited the function component into a class component, like so:
class App extends React.Component{
render() {
return (
<TheSameJSX />
);
}
}
Now, when I run npm start, I get an error:
Failed to compile
src/App.js
Line 4:19: 'React' is not defined no-undef
Search for the keywords to learn more about each error.
I imagine I need to add some setting somewhere that will automatically include React without me needing to explicitly import it at the top of every file. How do I do this? And why does this npm package not do that by default? I know a bit about javascript (and html and css), and have read a bit about React, but I am completely unaware of how npm or webpack works.
Thanks in advance!
EDIT: To clarify, I know how to import stuff with javascript. I can easily add import React from 'react'; to the file and make it work. However, I find it difficult to believe that adding an import statement to every single javascript file is the recommended method, and I don't understand why this example app wouldn't be set up so as to avoid having to do that. Am I mistaken? Do I really need to manually import the same thing over and over again within the same project? Could I set a global variable to React so that I can use it from wherever?
In your default function component you're not extending any classes and just writing a simple function
function App() {
return (
<SomeJSX />
);
}
In class component, you're in fact extending the Class Component by React.Component provided by React default export object and hence you must import it from the package
//only use one of these
import * as React from "react";
import {Component} from "react"; // you can directly extend without writing `React.` with this import
import React from "react"
So your code would be
import React from "react";
class App extends React.Component{
render() {
return (
<TheSameJSX />
);
}
}
Any of the above imports should be fine with a preference to the first and second one.

Is There Any Way to Push React State Into an Import Statement?

So in React, I import a certain file using a statement like so:
import Search from './Pages/search';
However, what if the file I want to import is going to be different every single time I call up a certain function? Would something like this -
import {this.state.fileName} from './Pages/{this.state.extension}';
where the state values are filled in by an outside function, work like I want it to? Say I wanted to download the file that is associated with that dynamic import. Would something like this -
<a href = {this.state.fileName} download> download </a>
allow me to download the file? Is there a better way to go about this? Curious to know.
If the page you want to import is going to change frequently, then may be your component can accept a fileName prop and then you can use that prop to dynamically import that file.
Something like this may be: https://codesandbox.io/s/nervous-bush-xf1zg. Here, the filename changes with each DynamicPage call and the filename that is passed in is imported dynamically within the DynamicPage function.
**Didn't completely understand what you were trying to do but hope this helps
import React, { lazy, Suspense } from "react";
export default function App() {
return (
<div>
<DynamicPage fileName="File1" />
<DynamicPage fileName="File2" />
</div>
);
}
function DynamicPage({ fileName }) {
const DynamicFile = lazy(() => import(`./${fileName}`));
return (
<Suspense fallback={"Loading.."}>
<DynamicFile />
</Suspense>
);
}
import React from "react";
export default function File1() {
return (
<div>
<h1>File 1</h1>
</div>
);
}
import React from "react";
export default function File2() {
return (
<div>
<h1>File 2</h1>
</div>
);
}
It seems like you need to share state between components.
You can:
Pass it as props manually from the parent to each child
or use React ContextApi library
or use some library such as
Recoil
Redux (more complex)

How to make react-datepicker display properly?

I cannot make the component react-datepicker display properly.
it actually displays like this.
I wish it could display at least like the documentation for the component does.
I first thought it was a dependency problem, and added all the dependencies the doc says are needed. The result is still the same.
Some stackoverflow questions talked about this and referred to a missing stylesheet. However I imported everything with npm, so that shouldn't be the problem.
My class component looks like this :
import React from "react";
import "./style.css";
import DatePicker from "react-datepicker";
class Filters extends React.Component {
constructor(props) {
super(props);
this.state = {
startDate : new Date()
};
this.handleStartChange = this.handleStartChange.bind(this);
}
handleStartChange = (date) => {
this.setState({
startDate : date
})
}
render() {
return (
<div className="filters">
<div id="filterbox">
<p id="titre">Filtres</p>
<DatePicker
selected={this.state.startDate}
onChange={this.handleStartChange} />
</div>
</div>
)
}
}
export default Filters;
I apologize in advance if the problem is very obvious, I'm quite new to reactjs.
You forgot to import the package css.
From the documentation:
import "react-datepicker/dist/react-datepicker.css";
I think you have to import the react-datepicker.css too, not only the package itself.
import "react-datepicker/dist/react-datepicker.css";
Below is a simple example of how to use the Datepicker in a React
view. You will also need to require the CSS file from this package (or
provide your own). The example below shows how to include the CSS from
this package if your build system supports requiring CSS files
(Webpack is one that does).
you haven't imported their css file.
import "react-datepicker/dist/react-datepicker.css";

VSCode bad javascript formatting

I am editing some javascript files (particularly, reactjs coed) in VS Code on Ubuntu 18.04. However, the "formatting" is really terrible.
Before:
import React, { Component } from 'react';
import './App.css';
import Dropzone from 'react-dropzone';
class App extends Component {
render() {
return (
<div className="App">
<Dropzone onDrop={this.onDrop} />
</div>
);
}
}
export default App;
After:
import React, {
Component
} from 'react';
import './App.css';
import Dropzone from 'react-dropzone';
class App extends Component {
render() {
return ( <
div className = "App" >
<
Dropzone onDrop = {
this.onDrop
}
/> <
/div>
);
}
}
export default App;
Previously, I was editing these files on Windows 10 in VS Code, and the formatter was great. Is there an extension I am missing? Or what am I doing wrong here. To format, I am using the "Format Document" keyboard shortcut.
Here are my current extensions:
The culprit for this behavior was Beatify extension on Vscode in my case. Disabling resolved the issue.
Here is the solution,
change the language manually to "javaScript React"
try with your favorite formatter(you can install vs code extensions such as "Prettier","beautify")
Cheers !
I personally use Prettier for JS and CSS formatting, and JS JSX Snippets for JSX in React. I have tried a lot of others, but with those 2 I can assure you your React code will look beautiful.

Categories