Binding properties of an array in an array - reactjs

This is not to start a discussion about Anugular vs REACT. I know at some point I will learn to love REACT. That is why I have started doing new apps in REACT. I just need some kind of confirmation whether I understand REACT correctly according to bindings.
I am making a function REACT component (arrow function) as I can read this is the new recommended practice. I have some data with an array of data with arrays of data. I am using all of this data to show and change content. In this specific sample I use it to toggle some menu's.
In Angular in the toggle you would have something like:
toggle(row){
row.toggle=!row.toggle;
}
As I understand it in REACT, if you want to change content, or have some states about toggle you need hooks (correct me if I am wrong). So in REACT you would apply all of your data to a setData(someData). Something like below:
const toggleMenu = (section, row) => {
console.log(section);
setDataList(
dataList.map(s => {
return s.id === section.id
? {
...s,
table: s.table.map(t => {
return t.id === row.id
? { ...t, toggleDropdown: !row.toggleDropdown }
: t;
})
}
: s;
})
);
};
So I have to find my specific objects in my data, update it, and pass it all back to the hook setter. I have two concerns here. Sometimes I meet customer requirements where they want tons of data on a home page (even when it is not best practices). That will still perform with Angular. Anyone has some experience whether REACT will perform in such scenarios with this approach (so much looping)?
Last have I misunderstood something, or is this normal practice when working with REACT - or have I over complicated the task? I have made a small sample here to show a sample case:
https://codesandbox.io/s/dropdown-for-multiple-maps-gmqpp?fontsize=14&hidenavigation=1&theme=dark
The answer I am looking for is Yes this is the way to go, or no you have totally misunderstand the concept because .. And a plus if somebody have experince with the performance for pages with a lot of content.

Related

Rendering issue with custom map component inside tabbed form of react-admin

I am using React-admin for a project where for some resources, I use the tabbed form to better organize the fields and inputs. I created a fairly simple custom map component based on react-leaflet, which I am using in these tabbed forms.
I am facing a weird issue where when the map is on other than the first tab, its contents do not display correctly. It appears as though the map "thinks" the viewport is much smaller than it actually is. Reloading the page (or even just opening developer tools in Chrome) forces re-render of the page and causes the map to start behaving correctly.
To better demonstrate, I created this simple Codesandbox project. It has a user resource from the RA tutorial with two tabs. Both contain an instance of the map component, but while the map on the first tab works correctly right away, the one on the second tab renders incorrectly.
I confess I am still kind of a noob at these things so I may well be doing something wrong, but I've been scratching my head for quite a few hours over this and I'd like to start eliminating possible culprits.
Any insight would be most welcome.
Thanks very much in advance for your time.
This issue has been discussed a lot in SO. If you search a bit you can find the reason. What you actually need to do is two things:
use setInterval in combination with map's invalidateSize method when switching a tab and then clean it on component unmount
use useEffect to change mapZoom and view since they are immutable.
SO since you use react-leaflet version 2.7.x you need to take the map instance using a ref:
const mapRef = useRef();
useEffect(() => {
if (!mapRef.current) return;
const map = mapRef.current.leafletElement;
const mapZoom = zoom || defaultZoom;
let intervalInstance;
if (!center && marker) {
map.setView(marker, mapZoom);
intervalInstance = setInterval(() => map.invalidateSize(), 100);
} else if (!center) {
map.setView([0.0, 0.0], mapZoom);
}
map.setZoom(mapZoom);
return () => clearInterval(intervalInstance);
}, []);
<LeafletMap
ref={mapRef}
center={marker}
zoom={defaultZoom}
className={classes.leafletContainer}
>
Demo

How to obtain a value from a file in another file thanks to the store

I have recently started a project in a team of three people. We've been learning some React for that, and when I explained to a friend what I was trying to do, he advised me to try it with Redux, but I'm not quite sure how I'm supposed to proceed.
My goal is to generate a code in an Arrival.js page, depending on a form that the customer filled, based on his first name and the date. I have the right function to generate that code. Now when the customer submits the form, a pop-up shows up, telling him "here's your code: CODE1245" for example. The thing is that this pop-up is a component located in another file named PopUpArrival.js and I can't manage to transfer the code generated in Arrival.js with the form's information.
So I tried to set up a store with reducers and actions, but I can't manage to find any actions that would fit my goals. Am I overthinking it by trying to use Redux? Or is there an easy way to do so? It's been three days and I'm quite lost and demotivated to be honest. Thanks if anyone took the time to read me and I'd be even more grateful if anyone shows up with a solution
If your components have a
parent-child relationship, then it would be easy to send the code as a prop to the child.
Sibling relationship, then What is the most simplest method of updating component's state from another component? Lets say components are siblings?
Not related at all, there are a lot of ways like cookies, local storage, context, redux, etc.
I guess using redux only for this purpose might be overkill. You can look at contexts in that case.
I think Redux maybe an overkill here. You can get this done without redux from how it looks. If you can consider the following flow.
Your Arrival.js will maintain state for the first name and the date. Your PopUpArrival.js should be a component in itself, which takes whatever text you want to show in popup as a prop. Based on when you want to trigger the popup logic, you should display the PopUpArrival component. I have tried to roughly write some code below which does the same.
const PopUpArrival = (props) => {
const { textToShow } = props;
return(
<div>{textToShow}</div>;
);
}
const Arrival = () => {
// maintains state for both name and date
const [showPopup, setPopupDisplay] = useState(false);
const togglePopup = () => {
setPopupDisplay((currentDisplay) => !currentDisplay);
}
const getTextToShow = () => {
return `${name}-{date}`; // whatever logic you have
}
return(
<>
<button onClick={togglePopup}>
Submit
</button>
{
showPopup && <PopUpArrival textToShow={getTextToShow()}/>
}
</>
)
}

Whether it is good to do lot of functionality in the setState Callback?

I am trying to check and uncheck a checkbox based on other conditions in screen..
I am printing an element using document.getElementById('foo') this is returning null even my element is present in screen and in DOM.
Please help me to solve problem.
I am developing code in which after API is being fetched state variable need to be set and do other functionality based on the respective state variable.
Is it feasible to do most of the logic inside the call back of the setState to promote synchronus way of coding or any other concepts are present to do the same?
this.setState({
filter:filterValue
},function(){
// Most of the coding logic goes here
})
Please suggest a prominent way if it is wrong
Well you definitely shouldn't use document.getElementById since it's against reactive programming logic but it's hard to say where is a problem if you don't provide example code.
Try to implement checkbox in React way:
const CheckBoxComponent = (isChecked) => {
return <CheckBox checked={isChecked ? true : false}/>
}
then in your return:
<CheckBoxComponent isChecked={yourFunctionWhereYouResolveWheneverIsOrNotChecked}/>
Another point is that you really won't to hold logic in setState callback. I guess you are a beginner. You should get better knowledge of functional programming. It's easier than handling state logic and mutation.
Judjing from your question you want probably something like that:
const yourAsyncCallToApi = async() => {
await someApiCall()
yourFunctionWhereYouResolveWheneverIsOrNotChecked() //it will be called as soon as u got data from api call
}
const yourFunctionWhereYouResolveWheneverIsOrNotChecked = () => {
// handle your conditions and return false or true based on them
}

When should I create a new React component?

When should I create a new React component, as opposed to defining a helper function in the same one?
In tutorials I usually see components like "StuffList" being defined that way:
StuffList = ({ list }) => {
const renderItem = item => {
return <div>{item}</div>
}
return list.map(item => renderItem(item))
}
The example above is really simple, but for both the list and the item the complexity can creep up quite a bit. So, I wonder what would be a good indicator that Item deserves to be extracted into it's own component? I'm not only talking about lists and items too, it's just the simplest example that came to mind.
As you might have guessed it depends. However, extracting a new component from an existing one can be considered to be a variation of the Extract Function refactoring. To paraphrase Martin Fowler from the highly recommended Refactoring book on when to use this refactoring:
If you have to spend effort looking at a fragment of code and figuring out what it's doing, then you should extract it into a function component and name the function component after the "what."
Other potential benefits here are being able to reuse the new component, reducing the original component's size (i.e. lines of code), and in the case of React it may help with rendering performance.
Edit: Also see this post by Kent C Dodds When to break up components into multiple components for another perspective.

React redux oop classes

coming from angular i used to have a class for every entity in my DB, such class encapsulated all entity behaviour.
for example users Class can look like
export class User{
static notValid(u){
return !!((u.id && u.id > 0 && u.fullname && u.fullname.length > 2 && u.picture) === false);
}
static fromArray(arr){
let pack = [];
for(let i=0;i<arr.length;i++){
pack.push(new User(arr[i]));
}
return pack;
}
constructor(u){
this.id = u.id || 0;
this.fullname = u.fullname+'' || 'N/A';
this.picture = u.picture+'' || '/imgs/logo.png';
this.role = u.role || 'N/A';
this.username = u.username+'' || '';
this.email = u.email+'' || '';
this.dob = u.dob || 0;
this.gender = u.gender+'' || '';
///START SETTING FLAGS AND VALIDATING DATA;
this.isValid = !User.notValid(this);
this.saved = this.id > 0;
let n = this.fullname;
this.nickname = n.split(' ').shift()+' '+n.split(' ').pop();
}
save(){
///IF NO ID, POST TO SERVER
if(!this.saved)return $http.post('/user',this.toJson);
return $http.put('user/'+this.id,this.toJson());
//tojson is defined in prototype;
}
identity(){
return {id:this.id,fullname:this.fullname,picture:this.picture,nickname:this.nickname};
}
}
}
so that my controller doenot know about how to save or update User, all it have is to trigger save() on user object.
Now React world, where every thing inside app is a component;
1. how can i replicate such approach inside react component ?
i read alot that there is presentational components and smart components. but what about Data Model component ?
2. if i port all my current class's to react should i also implement render method ? can i have multiple render functions to return different html based on page.
example above User can appear inside Profile will all details, and as a card in users list, so i should keep html for both inside class prototype ?
You seem to be a bit confused about React and what it is designed to do which is perfectly normal, coming from the Angular world.
The thing is, as far as React is concerned there is no such thing as a data model, only components. These components can have state (or they may not) and these components are rendered to the DOM.
Various types of components seem to have confused you as well. React is only concerned with how data is presented. Presentation and container components are distinguished from each other to make it easier for us to reason about how to manage application state.
To answer your specific questions:
1) If you are really adamant about keeping your existing structure and make it work with React, you don't actually need to do a lot of work. Your data model components are just JavaScript objects. You can pass them around and you can give them to components. When some event happens in the components, you can call the relevant methods in your objects. You will need to make sure that Angular specific methods are ported to pure JavaScript though.
I advise against this approach. It will work at first but you will find yourself in a maintenance hell in no time. Believe me, I'm building large scale React apps in my job and I have been bitten by similar decisions when I first started writing React components.
2) Certainly you could add a couple of React methods to your class definitions and also throw in the presentation code (that is, HTML) and presentation state. Then you would be able to render these components.
But that really is not the way to go about it. React doesn't decide on anything for you whereas Angular is very opinionated about this. First and foremost you should follow some tutorials on React. Looks like you have a sizable application in your hands, so I would advise you to look into Flux and Redux as well.
After that you should sit down and design how your application should work and how your state should look. After that it will be a breeze to go through the actual coding part.
You can NOT have multiple render methods in a React component, that makes absolutely no sense. React is pure JavaScript and JavaScript doesn't have any concept of overriding class members in the sense of classical OOP. Heck, JavaScript doesn't even have the concept of a class, that has been included in ES6 so people coming from class oriented programming languages wouldn't need to properly learn how the prototype chain works.
React components, and JavaScript objects in general, can only have one key. You can try this in your browser's console.
let a = {b: 1, b: 2};
console.log(a);
The object a will only have one b key and the value for that key will be 2.
Having said all this, you can delegate the actual rendering of a component to other objects based on some conditions using normal JavaScript coding methods. But this isn't how React is supposed to work. Your render method can be able to decide on what to render based on your conditions.
First of all, let me tell you that I can't answer your question.
It looks like you're new to React. I've never used this approach to create a class for every entity in DB, in React, ever. It's new to me. Maybe it works, maybe it doesn't. But what I'd suggest you is to get your hands dirty first with example projects in react. That'll answer most of your questions.
However, I can answer some of your questions-
Data Model component ?
Obviously, there is no such thing as Data Model component. React is all about unidirectional data flow. You want to use redux for state management in react. The components which are connected to this state are connected/smart components. Smart components pass the state to presentational/dumb components via props (properties). So there is that. All of the state comes from Redux or similar state management mechanism viz. Flux.
can i have multiple render functions to return different html based on
page.
No. One component contains only one render() method. That is precisely why I suggest you to please build some example apps in React.
If you want to learn React, here's what I'd recommend you, in that particular order-
React.js
Redux
Redux-thunk
Redux-saga
React is not a monolithic framework like Angular. It's just a library. And programmers are meant to throw different libraries together to build their apps.

Resources