React setFocus on Input field - security? - reactjs

Question: In React I read that you should not use 'ref' and 'findDOMNode' for security reasons. (insecurely accessing native DOM Elements...)
Is there another way to set the focus manually in input fields?

You can try the following:
function manualFocus() {
document.getElementById("text").focus();
}
return (
<div className="App">
<input type="text" id="text" name="text"></input>
<input type="text2" id="text2" name="text2"></input>
<button type="button" onClick={() => manualFocus()}>Manual Focus</button>
</div>
);

Related

Accessing refs in dynamically created child components react

How would I go about creating refs on child components created by a map function?
So I'm trying to use
"#react-google-maps/api"
to create input fields wrapped by google's autocomplete. However I'm running into an issue where I want to allow the user to create inputs (to add waypoints) and the only way to get their input into an arry is by using refs
<div className={style.form}>
<Autocomplete>
<input type="text" id="from" ref={originRef} placeholder="Enter Starting Location"/>
</Autocomplete>
{wayPoints.map((input, index) => {
return(
<Autocomplete key={index} onChange={e => handleInputChange(index, e)}>
<input type="text" id="from" placeholder="Enter Stop"/>
</Autocomplete>
)
})
}
<Autocomplete>
<input type="text" id="from" ref={destinationRef} placeholder="Enter Ending Location"/>
</Autocomplete>
<div className={style.add} onClick={addNewStop}>
<FaPlus/>
</div>
</div>
However since I'm creating child compoents I'm not sure how to use refs to solve the problem. I tried using a onChange handler function but if you click on the autocomplete recommendation it doesnt save.

URL search parameters gets replaced - Remix Run

I'm working on a search UI where I have quite a few filters which I want as URL parameters when someone selects/checks the options. I've used the technique as advised on the Remix.run docs to come up with multiple forms within the filters. Each time a group of Filters gets submitted, the selected old parameters get disappeared. Heres my code,
<Panel header="Status" key="status">
<Form
name="search"
action='/search'
method="get"
onChange={(e) => submit(e.currentTarget, { replace: false })}
>
<ul>
<li>
<Checkbox
name="status"
value="buy_now"
defaultChecked={status.includes('buy_now')}
>
Buy Now
</Checkbox>
</li>
<li>
<Checkbox
name="status"
value="on_auction"
defaultChecked={status.includes('on_auction')}
>
On Auction
</Checkbox>
</li>
</ul>
</Form>
</Panel>
<Panel header="Price" key="price">
<Form name="search" action='/search' method="get">
<Select
name="blockchain"
value={
blockchain
? options.filter((a) => a.value === blockchain)
: undefined
}
options={options}
placeholder="Blockchain"
type="white"
/>
<div className="d-flex align-center price">
<TextInput
value={min ? min : undefined}
name="min"
placeholder="Min"
/>
<span>to</span>
<TextInput
value={max ? max : undefined}
name="max"
placeholder="Max"
/>
</div>
<button
onClick={(e) => {
e.stopPropagation()
submit(e.currentTarget, { replace: false })
}}
className="btn primary-btn btn-lg w-100"
>
Apply
</button>
</Form>
</Panel>
How Can I get around this to have all the parameters without having to manage them on my own using React state?
Edit:- I want the first filter to be submitted automatically and the latter to be submitted on a button click.
Bit of a UI of what I'm trying to achieve,
Answer: After investing enough time to look through for shortcuts, finally understood that it's not one of the magic that remix.run does. use something like formik and update the state imparatively.
When you submit a form, the only values included are the one under the submitted form. The values from any other form are not included (fortunately!).
So I'd use a single Form with all the inputs under it (checkboxes as well as text inputs).
Then instead of a onChange on the Form, you can add something like an onChange handler on the checkboxes and submit the form inside imperatively (using a ref click on the submit button or something, I think using a ref on the form you need to submit all values in the submit function so a button ref click may be simpler).
Keep in mind that if you want to "restore" the field values after submitting, you need to return them from the loader function like this:
// Loader function
const url = new URL(request.url);
return {
results: [...],
values: Object.fromEntries(url.searchParams.entries())
};
Then in the component, use values from useLoaderData:
<input type="text" name="max" defaultValue={values.max || ""}/>
Added benefit: if you come back to this page (by clicking browser back for example), your search parameters and search results are still there!
I actually put up a stackblitz for you but I lost all my changes :(
It seems like you could just keep all fields in a single form and submit that form when the submit button is pressed.
Then onChange, check if the target's name is 'status', and submit the form anyway.
export default function App() {
const submit = (form) => {
form.submit();
};
return (
<form
name="search"
action="/search"
method="get"
onChange={(e) => {
if (e.target.name === "status") {
submit(e.currentTarget);
}
}}
>
<fieldset>
<legend>status</legend>
<label>
<input type="checkbox" name="status" value="buy_now" />
buy_now
</label>
<label>
<input type="checkbox" name="status" value="on_auction" />
on_auction
</label>
</fieldset>
<fieldset>
<legend>price</legend>
<label>
<div>blockchain</div>
<select name="blockchain">
<option value="option_1">Blockchain Option 1</option>
<option value="option_2">Blockchain Option 2</option>
</select>
</label>
<label>
min <input type="number" name="min" />
</label>
<label>
max <input type="number" name="max" />
</label>
</fieldset>
<button type="submit">Apply</button>
</form>
);
}
demo
Note: not sure what your motivation is to want to separate this into separate forms, but I think the magic you're referring to is that server state, URLSearchParams, FormData and UI are all aligned because they are using the same underlying data using only common web APIs.

How do I clear the textarea's value when clicked on the addbtn in reactjs?

I used the following code, but the text does not clear when I click the addbtn.
This is a reactjs project.
function Addpage() {
const[note, setnote] = useState("");
function textchange(e) {
setnote(e.target.value);
console.log(note);
};
function savenote(){
localStorage.setItem('savednotes', note);
setnote("");
};
return (
<>
<Headersmall/>
<br/>
<div className="addcard">
<h1>Add new note.</h1>
<div className="title">
<input type="text" className="titlebox" id="addtitle" placeholder="Title"/>
</div>
<br/>
<div className="note">
<textarea type="text" className="notebox" id="addtxt" placeholder="Note" onChange = {textchange}/>
</div>
<br/>
<button className="addbtn" id='addbtn' onClick = {savenote}>Save</button>
</div>
<br/>
</>
)
}
When you're setting the value of note as an empty string by doing setnote("") inside savenote() function, you ARE changing the value of the state variable note, but it doesn't reflect in the textarea because your textarea input doesn't have a value associated to it. Try adding value={note} which will mean that there will be a "set and fetch" relationship between the textarea and the 'note' state variable
<textarea
value={note}
type="text"
className="notebox"
id="addtxt"
placeholder="Note"
onChange={textchange}
>

onChange using Formik Validation

I'm currently having getting my input values to appear on screen as im typing. For example, I have a form that requires a first name and last name. Upon typing in those values I am trying to display the inputs typed onto the DOM. This was successful earlier with an onChange, and using this.state.firstName, this.state.lastName. I have implemented formik validation and currently my inputs only appear after I upload an image which has a set state.
I have an onChange passing its values
handleChange = event => {
this.setState({ [event.target.name]: event.target.value });
};
<---->
<Formik
initialValues={this.state.formData}
enableReinitialize={true}
validationSchema={userProfileValidation}
onSubmit={this.handleSubmit}
render={formikProps => (
<div className="container-fluid">
<div className="edit-profile">
<div className="row">
<div className="col-lg-4">
<div className="card">
<div className="card-header">
<h3 className="card-title">My Profile</h3>
</div>
<div className="card-body">
<div className="row mb-2">
<div className="col-auto">
<img
className="img-90 rounded-circle"
alt=""
src={
this.state.formData.avatarUrl
? this.state.formData.avatarUrl
: "https://iupac.org/wp-
content/uploads/2018/05/default-avatar.png"
}
/>
</div>
<div className="col">
<h4 className="mb-1">
{this.state.formData.firstName} {""}{" "}
{this.state.formData.mi} {""}{" "}
{this.state.formData.lastName}{" "}
</h4>
</div>
</div>
</div>
</div>
I am able to show what input on a setState but live like it previously shown.
You're trying to mix two separate things. Formik exist so that you don't have to manage your component level form state by yourself doing so is hard and formik does that for you.
You should pass an object containing form initial field values to initialValues prop instead of this.state.formData
To update a DOM value based on a field input somewhere, you can do this
<Field
name="email"
type="email"
onChange={e => {
// call the built-in handleChange for formik
handleChange(e)
// and do something about e
let someValue = e.currentTarget.value
this.updateEmailField(someValue) // Update a DOM element on this function
...
}}
/>

React react-localize-redux translation inside HTMLelement-properties

I have implemented the react-localize-redux for language-translations in an application i am working with. I do get the translations inside html-elements, but i am failing to get translations to work with html-element-properties. For example input value.
It works using like this:
<form onSubmit={this.handleSubmit}>
<label className="atom_required" htmlFor="name">
<Translate id="textexample" />:
</label>
</form>
But if i try this id returns object Object:
<div className="atom_bottomButtons">
<input
id="atom_bottomButtons__submit"
disabled
className="btn btn-primary"
type="submit"
value={<Translate id="textexample" />}
/>
</div>
Does someone know how to map properties of html-elements?
Simply use the render-prop API:
<div className="atom_bottomButtons">
<Translate>{
({ translate }) => {
return <input
id="atom_bottomButtons__submit"
disabled
className="btn btn-primary"
type="submit"
value={translate("textexample")}
/>
}
}</Translate>
</div>
See also: translate's API

Resources