Files structure with styled component and CRUD - reactjs

I do want to have a file structure by feature. But I'm using Styled Component and I have a lot of files.
For exemple in my project directory, which is an entity in my application, I have:
Projects.js ProjectList.js ProjectCreate.js ProjectShow.js Card.js CardHeader.js CardBody.js CardFooter.js TasksCounter.js ProjectDescription.js CardAdd.js ProjectDelete.js actions.js reducer.js saga.js constants.js
I could have more files but my pages are still under construction so I could add some more later. Should I split those files again? To have for example sub directories like Projects ProjectCreate ProjectShow put the common files in the root project directory and specific files into those three?
project
|_Projects
|_index.js
|_ProjectList.js
|_Card.js
|_CardHeader.js
|_CardBody.js
|_CardFooter.js
|_TasksCounter.js
|_ProjectDescription.js
|_CardAdd.js
|_actions.js
|_reducer.js
|_saga.js
|_ProjectCreate
|_index.js
|_Form.js
|_actions.js
|_reducer.js
|_saga.js
|_ProjectShow
|_index.js
|_ProjectHeader.js
|_ProjectContent.js
|_actions.js
|_reducer.js
|_saga.js
I saw a lot of different approaches in more than a dozen of tutorials but the examples are always really simple with just a couple of features.
Better solution maybe, using Ducks and put every Styled Components in the same file?

I usually make a separate folder called views for every react (custom) component.
views
- Cards
- index.js
- module.js
- test.js
- styles.js
- Button
- InputFields
- ...
- ...
Inside each view, notice that there is an index.js that has the react component. The module.js will contain reducers and actions if any. test.js will have tests regarding that component only and finally styles.js or styles.css/scss will have styles

Related

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.

How to import SCSS on Component Level with Next.js

I am coming from a CRA background and working my way through Next.js version 9.4.2
My project tree looks something like this :-
pages/
_app.tsx
index.tsx
components/
Navbar/
index.ts
Navbar.tsx
Navbar.scss
Inside my Navbar.tsx I have a statement import './Navbar.scss';
This gives me the following error :-
./src/components/Navbar/Navbar.scss
Global CSS cannot be imported from files other than your Custom <App>. Please move all global CSS imports to src/pages/_app.tsx.
Read more: https://err.sh/next.js/css-global
Location: src/components/Navbar/Navbar.tsx
The error, as mentioned, goes away if I move the import Navbar.scss statement to pages/_app.tsx
I know I can switch to Navbar.module.scss, but I don't want to go down the route of modular scss as I expect my scss to get complex I would like to stick to the manner in which I write my scss and not keep finding work arounds to issues that might arise later. I am open to being convinced here but I have not found good read ups on this to choose it as my path.
So by the looks if it, I am stuck with importing all <component>.scss files in _app.tsx. This will leave me with a long list of <component>.scss imports in my _app.tsx and I will also be left with a lot of <component>.scss files for Components that might conditionally not render.
What are my options here ?
Your Navbar.scss file is not named properly.
Let's say your stylesheet contains something like...
$color: red;
.someclassselector {
color: $color;
}
Component stylesheet files have to be named in the following convention for next.js to compile them as addressed in next's css getting started guide
<TheComponent>.module.scss
be imported like this:
import styles from './<MyComponent>.module.scss>';
and be applied to the component like this:
<TheComponent className={styles.someclassselector} />
Not really an expert but it seems that you should stick to class selectors as global selectors can only be declared if you import them in pages/_app.js. You may name a main.scss file to use Global or Tag Element selectors like h1 {},h2{}, * {}, etc.

How to use SCSS variables into my React components

I am working on a React project that follows this structure
src |
components |
Footer |
index.jsx
styles.scss
Header |
index.jsx
styles.scss
scss |
helpers.scss
variables.scss
...
main.scss
Into my variables file I was using the css custom variables so, all them where on :root and I can access them in my components styles.
When I wanted to create the dark colours I wanted to use the SCSS function darken, but it does not evaluate them and throws an error saying that var(--blue) is not a valid colour.
As a solution I decided to move all the variables into a SCSS variables but when project is building it throws another error that says that a $blue is not defined.
The unique solution possible I can use, it is to include the variables file in all the styles files but, I do not know if there are a better solution for the structure that I am using.
From React 17
To access your scss variables into the react component, you need to do something like that
Install node-sass as a dependency or dev dependency
No need to do any config change in webpack
import as a module <-- main point
variables.module.scss
$color: skyblue;
$primaryColor: red;
:export {
color: $color;
primary-color: $primaryColor;
}
App.js
import variables from '<YOUR_PATH>/variables.module.scss';
const App = () => {
console.log(variables);
}
If you don't want to use styled-component
then you can follow this link.
https://til.hashrocket.com/posts/sxbrscjuqu-share-scss-variables-with-javascript
I use a similar structure to organize my .scss files. I like having the styles in the same folder as the component. However, I import all scss files to my main.scss file. This helps avoid style conflicts in the DOM.
main.scss
import "./scss/helpers.scss"
import "./variables.scss"
import "./Footer/style.scss"
import "./Header/styles.scss"
Make sure to name your files with an underscore so that all the files get merged on compilation. Note you don't need to name the underscore in the import.
_helpers.scss
_variable.scss
_style.scss
Using this method you only need to import styles once into your app. index.jsx
There are different ways I can recomend you to tackle this.
1- Duplicate the values of those variables. Add them both on your variables.scss and as constants in some other file, maybe config.js or constants.js that way you'll be able to reference these values from your react components, the downside to this, is you'll have to remember to change them in two places if you have to modify the value.
2- Consider using styled-components. With styled components you can define your styles within your components, using variables or props within the styles.
3- Use some mechanism to define these variables in a single file or as environment variables, and setup your build process to be able to import these values into js and scss files.
It is possible to use custom variables with that project structure using css-vars mixin.
After proposing the option to evaluate custom variables before executing the SCSS function, a guy suggested me this mixin. I have just tested and works pretty nice.

reactjs - import 3 levels deep react

I am using react and was trying out the new context API for my project which is a "Reddit clone". So my Context is created in a file named provider.js which is in the src folder alongside App.js. Now, I have created a HeaderComponent in its own folder which imports the Context in the following way:
import Context from '../provider'
I have created another component called LoginComponent inside the HeaderComponent. And, the LoginComponent is in its own folder. Now, I have imported Context in the following way:
import Context from '.../provider'
The ../ import worked fine but the .../ imported throws and error.
Failed to compile.
./src/HeaderComponent/LoginComponent/index.js Module not found: Can't
resolve '.../provider' in 'C:\Users.......\reddit\reactfe\src\HeaderComponent\LoginComponent'
Every step up in the folder structure is a .. followed by a /.
import Context from '../../provider'
The number of dots don't have the meaning you seem to think they do. Things to remember:
../ Up one directory.
../../ Up two directories (and so on).
./ Same directory as the current one.
With this in mind, since you need to go up one directory (from LoginComponent to HeaderComponent) and then up one directory again (from HeaderComponent to src) because that's where provider.js resides, you need to do:
import Context from '../../provider';
If you run in your console ls -la you see the . and ... So the . it's the current local where are you, and the .. it's a reference to the parent folder (one level up). So if you need back two folders you need put this two times, this way ../../.
In your case import Context from '../../provider'

React Component Names Like BEM

I got some great react best practices are here. Grateful to AirBnB https://github.com/airbnb/javascript/tree/master/react
So... Got this idea like BEM for classes, but use for component names and children. A bit tired of happening to search around components.
Like so.. Component__childName__childName__childName.jsx
I have this idea however and would like to know:
Is this a bad practice?
Are component names going to be come unwieldy?
Sort of links the file names all together when its box in a box in a box in a box.
Could get as short as say:
Component__List.jsx
Component__List__Item,jsx
UpdAte question:
Could a separate directory for each component be useful? I am seeing that as well indifferent projects.
For example:
|-Components
|--ExampleComponent
|---Component.jsx
|---ComponentList.jsx
|---ComponentItem.jsx
|---ComponentItemDetail.jsx
|---Component.scss
|--AnotherOne
|---AnotherOne.jsx
And so on...
I guess you are asking for a good naming practice and is it ok to name your components like Component_User.jsx, then if it has a header, Component_User_Header.jsx, then if the header has a label Component_User_Header_Label.jsx. If you are asking smtg else you can just ignore the rest :)
I guess a better approach would be to put related components into a domain folder: such as under user directory index.jsx would be your main component and index.css would be your main css for that component. Then for each subcomponent you can create a similar named files as a sub-directory.
user // main directory
image //sub directory
index.jsx //component file import index.css
index.css //css for this component
header
index.jsx //component file import index.css
index.css
index.jsx //main component file import sub-directories index files to use those components
index.css

Resources