Positioning a component in .jsx-file and not via a .css-file - javascript

I'm looking for a solution how to position a component in a .jsx-file instead of a .css-file because I have multiple files of the same component, but each one is responsible for different tasks so I need them in different positions of the page.
I don't want to have multiple copies of the same file with only a minor change of the css class - I would rather like to add changes to the .jsx-file, or if you know how to achieve that using a .css-file, please let me know.
Example:
I have a 'Fish'-file which gives the basic structure of what the fish will look like.
I have to make multiple fish files(i.e fish.jsx, fish1.jsx, fish2.jsx) because they each use a different css class for their positioning. How can I reduce the amount of Fish.jsx to one either by adding to the original fish.jsx or .css-file used?

The way I would approach your problem would be something like this
import Fish from './Fish';
import './Fish.css';
// other stuff
const FishContainer => (
{[...Array(10)].map( (_, i) => <Fish className=`fish-${i}` /> )}
);
export default FishContainer;
And in your css file
.fish {
&-1 {}
&-2 {}
// etc
}

Related

what is the cleaner way to write large strings in react website?

I need to render large text in some places and sometimes small descriptions on my website.
The text is not in English language what makes left-right vs right-left to be really annoying.
Moreover, the componenet containing the text became very large and hard to maintain.
I'm not a pro yet but i'm sure there is a best practice for my question.
Currently, my way to solve the large text is to render small components with the text only. (ofc I can create another api that includes the desired text but not in this case. I want to seek other way)
//folder contain MainCompoenent.jsx and TextComponenet.jsx
MainCompoenent:
import React from "react";
import TextComponenet from "./TextComponenet.jsx"
const MainCompoenent= () => {
return <div>
<ManyHtmlTagsandExtraLogic>
<TextComponenet />
</ManyHtmlTagsandExtraLogic>
</div>;
};
export default MainCompoenent;
TextComponenet:
import React from "react";
const text = `lorem but not in English language * 1000 `;
const TextComponenet= () => {
return <div>{text}</div>;
};
export default TextComponenet;
Not sure if you meant this with "I can create another API", but in my opinion, best way to handle this is have a component similar to the one you created, TextComponent, but make it reusable by using props.
Then, for an example, you can create one separate file called i.e. "alltexts.js", where you can either create (and export) one JSON object with all the texts that you need, or you can create a separate variable for each of your texts and export them.
Then on the parent component that calls the text component, you can import the "alltexts.js", and pass the specific text as props to the TextComponent like
<TextComponent text={myText} />

Call a function on a react child functional component from parent

I have a very large and complex React application. It is designed to behave like a desktop application. The interface is a document style interface with tabs, each tab can be one of many different type of editor component (there are currently 14 different editor screens). It is possible to have a very large number of tabs open at once (20-30 tabs). The application was originally written all with React class components, but with newer components (and where significant refactors have been required) I've moved to functional components using hooks. I prefer the concise syntax of functions and that seems to be the recommended direction to take in general, but I've encountered a pattern from the classes that I don't know how to replicate with functions.
Basically, each screen (tab) on the app is an editor of some sort (think Microsoft office, but where you can have a spreadsheet, text document, vector image, Visio diagram, etc all in tabs within the same application... Because each screen is so distinct they manage their own internal state. I don't think Redux or anything like that is a good solution here because the amount of individually owned bits of state are so complex. Each screen needs to be able to save it's current working document to the database, and typically provides a save option. Following standard object oriented design the 'save' function is implemented as a method on the top level component for each editor. However I need to perform a 'save-all' function where I iterate through all of the open tabs and call the save method (using a reference) on each of the tabs. Something like:
openTabs.forEach((tabRef) => tabRef.current.save());
So, If I make this a functional component then I have my save method as a function assigned to a constant inside the function:
const save = () => {...}
But how can I call that from a parent? I think the save for each component should live within that component, not at a higher level. Aside from the fact that would make it very difficult to find and maintain, it also would break my modular loading which only loads the component when needed as the save would have to be at a level above the code-splitting.
The only solution to this problem that I can think of is to have a save prop on the component and a useEffect() to call the save when that save prop is changed - then I'd just need to write a dummy value of anything to that save prop to trigger a save... This seems like a very counter-intuitive and overly complex way to do it.... Or do I simply continue to stick with classes for these components?
Thankyou,
Troy
But how can I call that from a parent? I think the save for each component should live within that component, not at a higher level.
You should ask yourself if the component should be smart vs dumb (https://www.digitalocean.com/community/tutorials/react-smart-dumb-components).
Consider the following:
const Page1 = ({ onSave }) => (...);
const Page2 = ({ onSave }) => (...);
const App = () => {
const handleSavePage1 = (...) => { ... };
const handleSavePage2 = (...) => { ... };
const handleSaveAll = (...) => {
handleSavePage1();
handleSavePage2();
};
return (
<Page1 onSave={handleSavePage1} />
<Page2 onSave={handleSavePage2} />
<Button onClick={handleSaveAll}>Save all</button>
);
};
You've then separated the layout from the functionality, and can compose the application as needed.
I don't think Redux or anything like that is a good solution here because the amount of individually owned bits of state are so complex.
I don't know if for some reason Redux is totally out of the picture or not, but I think it's one of the best options in a project like this.
Where you have a separated reducer for each module, managing the module's state, also each reducer having a "saveTabX" action, all of them available to be dispatched in the Root component.

Using Linked Lists in Checkerbox selection List react-native

I created a Linked-List data structure in my react-native app that I want to move between screens and then pick a node based on a checkerbox selection menu.
I understand that I can move the list using react-native-navigation, so now I would like to display the list with a checkerbox list to select multiple nodes and perform actions on them. The problem I see is that checkerbox lists use defined const arrays of items that are then listed.
The whole reason I went with linked-lists is that I need the list to dynamically update. (It may be more beneficial to use an array of large size instead, but each element within the node is somewhat large and I am unsure what effect a large array would have.)
Is there a way to input a linked list into a checkerbox list or would I have to create an array?
How would I go about either option if they need to dynamically update?
It may be more beneficial to use an array of large size instead, but each element within the node is somewhat large and I am unsure what effect a large array would have.
JavaScript arrays only hold references to the objects they store since it is a dynamic scripting language supporting prototype based object construction. Because of this, each element's size will not affect the array performance.
Another possibility is to extend the built-in Array class in your Linked-List data structure to ensure compatibility.
Your decision on using an Array or a Linked-List should be based on the List operations your app uses the most. There are a lot of articles about that.
Is there a way to input a linked list into a checkerbox list or would
I have to create an array?
How would I go about either option if they need to dynamically update?
There are some git repositories that add support for what you want to achieve (here is an example, feel free to explore npm for more).
Another possibility, if you want your items to dynamically update, will be to encapsulate them in a React.Component for rendering:
// YourNode.js
import React, { Component } from 'react';
import { CheckBox } from 'react-native';
export default class YourNode extends Component {
constructor(props) {
super(props);
this.state = {
checked: false,
};
}
selectItem = () => {
const { onPress } = this.props;
// Update the state
this.setState({ checked: !this.state.checked });
onPress();
};
render() {
const { node } = this.props;
// You may want to render more things like `Text` or `View` components based on
// the node's content
return (
<CheckBox
value={this.state.checked}
onValueChange={this.selectItem}
/>
);
}
}
import YourNode from './YourNode';
// YourScreen.js
render() {
//...
// This will render a `YourNode` component for each one of your nodes.
{yourList.map((item, index)) => {
return (<YourNode node={item} onPress{() => this.selectedNodes.push(item)}>)
}
}
}

Setting className string dynamically Javascript \ React

In my current project, I'm setting up mobile support the following way:
1) I'm creating all the relevant components both for desktop and mobile. On most of my pages, they're the same.
2) I'm creating two .scss files, one for desktop and one for mobile (determined by a media query covering the entire file)
3) I'm then attaching both styles in the className of my components, and then only the relevant file gets set. It looks like this:
// Styles
import styles from '../../components/Timeline/timeline.scss';
import mobileStyles from '../../components/Timeline/mobileTimeline.scss';
// Example component
<Row className={`${styles.container} ${mobileStyles.container}`}>
<div className={`${styles.myComponent} ${mobileStyles.myComponent}`}/>
</Row>
It works great, but in order to make the code a bit cleaner, I decided to write a helper function to generate the entire string for the className ->
const setStyle = styleName => `${styles.styleName} ${mobileStyles.styleName}`
However, setStyle always returns 'unidentified' (*the function is defined after the styles imports of-course)
I think I understand why it happens, but I wonder, is there a way we could dynamically access style object properties like that?
Thanks in advance!
To get a property from an object given the key name in a variable, use the bracket notation:
const setStyle = styleName => `${styles[styleName]} ${mobileStyles[styleName]}`
This assumes that styles and mobileStyles are available in the scope of the function, otherwise you would also need to pass them:
const setStyle = (styleName, styles, mobileStyles) => `${styles[styleName]} ${mobileStyles[styleName]}`

How to change only render of a React component

I want to use react-id-swiper library which exports a component named Swiper.
This is its render method:
render() {
const { containerClass, wrapperClass, children, rtl } = this.props;
const rtlProp = rtl ? { dir: 'rtl' } : {};
return (
<div className={containerClass} {...rtlProp}>
{this.renderParallax()}
<div className={wrapperClass}>
{React.Children.map(children, this.renderContent)}
</div>
{this.renderPagination()}
{this.renderScrollBar()}
{this.renderNextButton()}
{this.renderPrevButton()}
</div>
);
}
}
This component perfectly matches my needs, except that I need to place pagination in an outer place (outside of the containerClass element).
One possible solution is to inherit Swiper class and change only it's render method. However Facebook docs are explicit to not use inheritance and use composition instead.
What's the best way to move the pagination outside of containerClass?
Can it be done with composition?
As it stands there is not much you can do, since this component is render specifically in this structure align with a secondary library. In the rebuildSwiper function you can see it passing it the dom elements to this other library to bind and handle all interactions.
Depending on the flexibility of the secondary app you could move the render order. To do so I would first evaluate what the capabilities are of the inner library, then fork this repo and publish updates using the a scoped package such as #<username>/react-id-swiper.
I think composition would be well and good, but because you're using a library and not able to design the source class, I think inheritance is your only option.
I would recommend simply extending the Swiper class. You can write your new render method in a way that would allow for composition reuse moving forard if you want to follow these recommended practices, but I think it's safe to trust your gut in this case.
I'll be watching this question and am curious to see how others would approach it and what you're ultimate take is, too.

Categories