How to call or use a .js file using onclick Reactjs functional component - reactjs

I have .js file called Edit which is used for edit purpose. I have another .js file called Add. I have a dialog box in edit.js which will open when I click a button. But I don't want to use a button instead I want to get that a dialog box when I click anywhere on box. I tried using onclick in div tag but I didn't get any response.
this is the output
so if you observe we got a edit button there if click it I am getting form/dialog box for editing the content. but I want that form or dialog box to open when I click anywhere on the yellow box.
<div id='color' className='div2' key={item.id} style={{width: 340,
# border: '5px solid white',textIndent:-30,paddingRight:32,paddingLeft:40,whiteSpace:'pre',paddingTop:15, backgroundColor:item.currentColor}} onClick={()=>{editpage(item.id)}} >
this is what I used for calling function for getting form in another .js file. It is part of a mapping function.` there is a onclick event I used that whenever I click on the box or content which is all under div tag I need to go to that function and there go to edit and then form but it didn't work
the function to which it goes is this:
const editpage=(id)=>{ <Edit id={id}></Edit> }
I want to send a id as a parameter which is passed to Edit.js.
I used <Edit/> because it is a another js file which I am importing in Add.js file.
I am not able to get the output can you please me with this.
how I can use this when I click on color box should open a form which is indeed in another file.

This is successfully calling a function on the click event:
onClick={()=>{editpage(item.id)}}
But what does that function do? Absolutely nothing:
const editpage=(id)=>{ <Edit id={id}></Edit> }
The function doesn't return anything (not that returning from a click handler does anything either of course), doesn't perform any operations, nothing. It's just a single JSX expression.
Take a different approach entirely. Add your component to the markup, but wrap it in a condition based on state. For example, consider this state value:
const [openEditPage, setOpenEditPage] = useState();
The purpose of this state value is to keep track of which item.id should currently have its "edit" component visible. (Default to undefined so none are visible by default.)
Use this value when rendering the components:
<div id='color' className='div2' key={item.id} style={/*...*/} onClick={()=>{editpage(item.id)}}>
{openEditPage === item.id ? <Edit id={item.id}></Edit> : null}
</div>
So in this case the <Edit> component will only be rendered if openEditPage === item.id. Which is what the editpage() function can do:
const editpage = id => setOpenEditPage(id);
Clicking on the <div> would invoke the editpage function, which updates the state value, which triggers a re-render, and in the new render the <Edit> component is shown because the condition would be true.

Related

#testing-library/React : Clicking outside of component not working

I'm using react testing library to test my component built with FluentUI.
Here is link:
https://codesandbox.io/s/keen-borg-2tqmj?file=/src/App.spec.js
The code is basically a pasted snippet of the example code of Dialog component from FluentUI docs site. The behavior that I'm testing is:
User opens the dialog
User clicks outside of the dialog
onDimiss prop of the component should be fired.
It works when I'm playing with it manually however it seems that I failed to simulate a click outside of the component with testing library.
I tried using userEvent.click(document.body) as mentioned in this post but got no luck
Does anyone has any idea how to make test work?
It is not working because the Dialog component is not listening for the onClick event on the body, so what you need to do in this case is to find the actual element that is being clicked, observing the dom you'll find that the overlay is a div with some overlay classes on it.
<div
class="ms-Modal is-open ms-Dialog root-94"
role="document"
>
<div
aria-hidden="true"
class="ms-Overlay ms-Overlay--dark root-99"
/>
The problem now is to find a way to select it. Unfortunately, you cannot select elements in RTL by their className, so you need to use another selector; in this case, we can get the parent element by the role and then access the first child.
const onDismiss = jest.fn();
const { getByRole } = render(<App onDismiss={onDismiss} />);
UserEvent.click(screen.getByText("Open Dialog"));
const document = getByRole("document");
UserEvent.click(document.firstChild);
expect(onDismiss).toHaveBeenCalled();
https://codesandbox.io/s/hungry-joliot-tjcph?file=/src/App.spec.js

React element events

So I'm trying to style an element when user focuses/hovers on an input/button. The way I'm doing it is by using a state and setting it to true or false if the user has hovered or focused but find it very repetitive and will take a lot of code, considering I would have to create a focused and hovered state for each button or input.
For example, I'm doing :
const [hoveredBtn, setHoveredBtn] = useState(false)
const [themecolor, setThemecolor]=useState('red') //this state is being from firebase, red would
//just be an example, it can be whatever the user sets it to.
return (
<button
onMouseOver={()=>setHoveredBtn(true)}
onMouseLeave={()=>setHoveredBtn(false)}
style={hoveredBtn?{backgroundColor: themecolor}:{backgroundColor:"white"}}
>
Button
</button>
)
Therefore, I would need to create a hovered variable for each button or input I have and im looking to know if there is a way to do it like this, but when I tried I get an error:
return (
<button onMouseOver={this.style.color=themecolor} onMouseLeave=
{this.style.color='white'}>Button</button>
)
You can’t specify pseudo-classes using inline styles. That means :hover, :focus, :active, or :visited go out the window rather than the component.
source: https://www.freecodecamp.org/news/react-styled-components-inline-styles-3-other-css-styling-approaches-with-examples/
style.css:
.myComponent:hover {
// define style
}
myReactComponent.jsx:
import './style.css';

React change class of component without using state

How can I change the className or style of a div without using state or any third party libraries? Lets say I click on a button, and I need to change the background color of a div how can I do that?
<Affix onChange={() => change css or class} offsetTop={60}>
<div>...</div> // Change css of this div
</Affix>
You can change any attribute or property of a Component (Element) in React by using basic javascript functions.
onClick={(e) => {
e.currentTarget.setAttribute("src", newUrl);
}
Will change an image the moment you click on it, without using Ref or State.
event.currentTarget will give you the reference to the component that fired that particular React.MouseEventHandler event, and with the Element's reference, you can manipulate it at will.
This is particularly useful when you need to change an attribute in a component in a map loop without needing to keep track of it.
Edit:
A friend of mine just gave me a better one for classes in specific:
e.currentTarget.classList.add('my_custom_klass')
You can either do it manually using state:
const [myClass, setMyClass] = useState('bgColor-white');
return (
<Affix onChange={() => setMyClass('bgColor-black')} offsetTop={60}>
<div className={myClass}>...</div> // Change css of this div
</Affix>
)
Or you can use a library that handles dynamic styling. I use and recommend styled-components

Mimic React custom component

I have a custom Reactjs component to display Pagination with next/previous buttons at the bottom of a grid. Now, the business needs to display the same component on top of the grid as well. How to display the previous /next button events based on the input provided in prev/next buttons at the bottom of the grid?
I tried using javascript innerHTML to mimic the behaviour. It works only with the display. It does not attach the event listener of the buttons. I tried even with
document.querySelector.addEventListener('click', ()=>{console.log('test')})
It does not work. Is there a better way to do with react.
I am going to just add some more content to Shmili Breuer answer.
If i understood you correctly you have 2 navigations, one at the top one at the bottom. The way you connect them would be through a state of you component, or a parent component if you are using functional component to render pagination stuff. So if you change the state it will reflect on both of your navigations. Also you can use only one function here, by passing a parameter, im gonna copy a code from before mentioned answer.
// first create a function
nextFunction = (condition) => {
if(condition){
this.setState(prevState=>({
page: prevState.page-1
}))
} else {
this.setState(prevState=>({
page: prevState.page+1
}))
}
}
// then use it in your button
<button onClick={() => this.nextFunction(some condition)}>Next</button>
Just put that component on top and bottom
<Grid>
<Pagination />
{...someOtherComponents}
<Pagination />
</Grid>
it's ok in react. Optimization that you want to do is overhead.
In react you would add an onClick attribute to an element you want to handle a click on.
Something like this
// first create a function
nextFunction = () => {
do next functionality....
}
// then use it in your button
<button onClick={() => this.nextFunction()}>Next</button>
This way you can have both top and bottom pagination call the same function.
Hope this helps

reactjs componentWillMount not calling every time when i open modal

i am displaying table data inside modal dialog, when i click table row to edit data it will open another modal dialog, here i am getting row data by using clicked row id inside componentWillMount(). but when i close edit modal dialog and try to edit other table row componentWillMount() will not called. so edit modal dialog is empty. why componentWillMount not calling every time?
As Nir H already mentioned, Dialog component mounts into the dom only once, and then after you close it, becomes invisible (by changing the left position to -10000px) but still present inside the DOM.
So its clearly that componentWillMount and componentDidMount methods will be called only once. If you want to open Dialog component with different options every time, you can do the folloving:
Save ref to the Dialog component instanse in the parent component:
ref={instance => {this.RowDialog = instance}}
Then you can open Dialog by using it handleOpen method:
onRowClick = (event) => {
this.RowDialog.handleOpen();
}
I used following steps to fix it.
i used {(this.state.open) ? <Dialog open={true} ></Dialog> : null
second step by unmounting the component componentWillUnmount() { }

Resources