How to display a text message after onClick in react JS? - reactjs

I am pretty new to ReactJS. I have created a Form that accepts a two inputs and has a button that invokes the onclick() function. I want to display a simple message like "Action complete" below the Form when the onclick() function is complete. I don't want to use alert, but display the message on the webpage itself.
What is the best way to do this?

You can either create an element with JS and append it to the form body or you can have an invisible div/p/whatever element that gets his text modified inside the onclick function and its css class/css style too so that it appears. If you need specific code solutions you can paste your code here :)

You may want to look into state hooks with react, they are found here
https://reactjs.org/docs/hooks-state.html
It sounds like you may want something similar to the following;
const Search = () => {
const [showResults, setShowResults] = React.useState(false)
const onClick = () => setShowResults(true)
return (
<div>
<input type="submit" value="Search" onClick={onClick} />
{ showResults ? <Results /> : null }
</div>
)
}
const Results = () => (
<div id="results">
Some Results
</div>
)

Related

How to make my button tag to trigger my input tag secretly, without seeing my input tag?

Question:
I am new to React. For some reason, I would like to hide my input tag. On the other hand, I want a button tag to perform what my existing input do, which is to load file and set the content of files into variables.
Problem explanation:
My input tag could load files and set the file content into variable. However, the style of input tag is not my liking and i prefer the style of my button components.
So, as far as I know, only input tag could do the loading file feature.
But since I have wrote the function I need in the input tag, which is to load file and load the content into a variable. I want to see if I can make the button pretended as input. So I dont have to rewrite code again
So, is it possible to let my button to somehow pretend the input tag?
Below is my present code:
import React, { useState } from "react";
export function App() {
const [files, setFiles] = useState("");
const handleChange = e => {
const fileReader = new FileReader();
fileReader.readAsText(e.target.files[0], "UTF-8");
fileReader.onload = e => {
console.log("e.target.result", e.target.result);
setFiles(e.target.result);
};
};
return (
<>
<h1>Upload Json file - Example</h1>
<input type="file" onChange={handleChange} />
<br />
{"uploaded file content -- " + files}
<br />
// I expect when I click on "Import file", it could also load file like the input tag and perform what my existing input tag do
<button >Import file</button>
</>
);
}
I can see a couple of ways.
One is to give the input element an id and then insert a label inside the button with the for attribute set to the same id.
<input id="upload" type="file" onChange={handleChange}/>
and
<button><label htmlFor="upload">Import file</label></button>
(note: only the clicking on the text will trigger the input, so you might need some css here to make the label fill the button completely)
Another would be to use a ref on the input and use it to trigger a click on it from your button.
const inputRef = useRef<HTMLInputElement>(null);
const handleButtonClick = () => {
if (inputRef.current) inputRef.current.click();
};
<input ref={inputRef} type="file" onChange={handleChange}/>
<button onClick={handleButtonClick}>Import file</button>
Both attempts shown at: https://codesandbox.io/s/optimistic-sound-l0hhzm

How to link a text input with associated error message in a reusable React component

I have a React component called TextInput which looks like this:
const TextInput = React.forwardRef<HTMLInputElement, ITextInputProps>(
({ error, ...props }, ref) => {
return (
<>
<input
type="text"
aria-describedby="" // 👈 see here
ref={ref}
{...props}
/>
{error && (
<p> // 👈 how can I reference this?
{error}
</p>
)}
</>
)}
)
For accessibility, I am trying to link the error message to the field using aria-describedby.
In a normal HTML document I would just use the id of the paragraph tag, but with reusability in mind, I would like to learn how to do this in a React-like way.
The use of refs comes to mind, but I'm not sure how to apply it in this scenario.
I would say that the best way to do this is to create a required prop that handles the ID and you apply that ID on the aria fields.
With that in mind, if what you wanted is to generate the data dinamically you could use a useEffect running it only once and setting a state inside it.
function Component() {
const [describedBy, setDescribedBy] = useState()
useEffect(() => {
setDescribedBy(generateRandomString());
}, [])
return (
<div aria-describedby={describedBy}></div>
)
}

useRef is getting cleared when filtering array of objects

I've created one Demo Application where I've been able to add comments while clicking on the chat icon textarea will be expanded, currently, the functionality is I've created a reference using useRef of that particular text area using unique id, and I'm saving comments to that reference array, & rendering on UI using ref.current Method, everything is working as I expected but when I click on those filter buttons, the reference is getting null! my requirement is even though I do filter comments should be persisted!
Any suggestion, Any new Approach except using useRef would be Appreciated! Thanksyou!!
Here's my codesandbox link
https://codesandbox.io/s/proud-resonance-iryir7?file=/src/App.js
Your comment ref should only contains comments, not includes textarea element. So you should create a component to handle textarea value
const TextArea = ({ value, handleSaveComment }) => {
const ref = useRef(null);
return (
<>
<textarea
placeholder="Enter Here"
ref={ref}
defaultValue={value}
></textarea>
<div
className="save-button"
onClick={() => {
handleSaveComment(ref.current.value);
}}
>
Save
</div>
</>
);
};
and use it in table
const handleSaveComment = (fsValidationId, value) => {
comment.current[fsValidationId] = value;
setExpandedId((prev) => (prev === fsValidationId ? "0" : fsValidationId));
};
<AccordionDetails>
<TextArea
handleSaveComment={(value) =>
handleSaveComment(row.id, value)
}
value={comment.current[row.id]}
/>
</AccordionDetails>
You can check full code in my codesandbox. Hope it help!

how to render a same component one or multiple time using event handler

I want to build form in Which there are some text fields as shown in picture
in this form there is a button and after clicking the Add Units button a new form will appear
how can i render this sub form by using button onClick Event-Handler and i also want to render it as many times as i click the button , if i click button one time then it shows the the sub form only one time if i click the button two times then it will show two times
-The main issue is I want the sub form to appear as many time i click the button
(optional if i want to remove the rendered sub form using a button click then please mention the code )
use of react hooks is preferable
you can ask me anything related to question
Here is an example of how to solve your problem. You don't need useEffect, and you don't need three separate state variables. You just need one array of objects.
import React, { useState } from "react";
import ContainerSlot from "./ContainerSlot";
function ReceiptContainer() {
const [containers, setContainers] = useState([]);
const handleAddContainer = () => {
// adding an empty object; you will likely need to
// initialize this object with whatever values are stored
// in the container form
setContainers((current) => [...current, {}]);
};
const handleRemove = (index) => {
const current = [...containers];
current.splice(index, 1);
setContainers(current);
};
return (
<div className="receiptContainer container">
{/* Heading */}
<div className="receiptContainer__heading mt-3">
<h4>Container Invoice</h4>
<hr />
</div>
<button onClick={handleAddContainer}>Add container</button>
<div className="receiptContainer__container">
{/* You will likely need to pass whatever values are in
the container to your ContainerSlot component */}
{containers.map((container, index) => {
const handleRemoveClick = () => {
handleRemove(index);
};
return (
<div
key={`container-${index}`}
style={{ display: "flex", alignItems: "center" }}
>
<div>
<ContainerSlot {...container} />
</div>
<div>
<button onClick={handleRemoveClick}>Remove</button>
</div>
</div>
);
})}
</div>
</div>
);
}
export default ReceiptContainer;
EDIT: updated to show how to remove an item

React Button Click Event Not working correctly

How come the following React Button Emitter is not working? It should display the word Apple, with button click.
function App() {
return (
<div>
<button onClick={handleClick('apple')}>
Test Button
</button>
</div>
)
}
function handleClick(props) {
console.log(props)
}
In order for it to get called on click you need to pass a function. Right now your code is invoking the function:
function App() {
return (
<div>
{/* Creates an anonymous function that calls `handleClick` */}
<button onClick={() => { handleClick('apple'); }}>
Test Button
</button>
</div>
)
}
By doing onClick={handleClick('apple')} what you are doint is to put the result of handleClick('apple') at rendering time, not onClick time.
onClick={() => handleClick('apple')} will work because you are creating a function and assign it to onClick, without executing it yet.
This is how React works, because what you are writing is actually just javascript (not html, even if it looks like so).
Your way would instead be perfectly ok if you were using Vue, for example, because in that case you are working in an html template (unless you don't want to use jsx..)

Resources