Cannot change text value of input element - reactjs

I'm learning React so sorry if the question is silly. Anyway, I'm trying to change the text of an Input element if the filtered variable is null, so I did:
const contactContext = useContext(ContactContext);
const text = useRef<HTMLInputElement>(null);
const { filterContacts, clearFilter, filtered } = contactContext;
useEffect(() => {
if (filtered === null) {
text.current?.value = '';
}
});
but on this line: text.current?.value = '';
I get:
The left-hand side of an assignment expression may not be an optional property access.
what I did wrong?
UPDATE
return (
<form>
<input
ref={text}
type="text"
placeholder="Filter Contacts..."
onChange={onChange} />
</form>
)

Error message is pretty clear about what's wrong in your code.
Optional-chaining is not valid on the left-hand side of the assignment statement and you get this error because of the following statement in the useEffect hook
text.current?.value = '';
You can only use optional-chaining on the right-hand side of an assignment.
You can replace your optional-chaining code to an if statement
if (text.current) {
text.current.value = '';
}

Related

How to condition a component to display certain information?

const handleChecked=(e)=>{
setForm({
...form,
[e.target.name]:e.target.checked
})
if(e.target.name == 'lowercase'){
showMinus(longitud)
}
}
const handleSubmit =(e)=> {
updatePassword(longitud)
activeLetters()
e.preventDefault();
}
file 1
const ShowPass =()=>{
let charactersLength = characters.length;
let allChar = ''
for(let i = 0; i<range.current.value; i++){
allChar += characters.charAt(Math.floor(Math.random()* charactersLength))
}
setPassword(allChar)
}
const showMinus=(minusculas)=>{
let allMin=''
let minLong = minusculas.length;
for(let i = 0; i<range.current.value; i++){
allMin += minusculas.charAt(Math.floor(Math.random()* minLong))
}
setMinus(allMin)
}
//¿Que tipo de carcarter es?
const activeLetters =()=>{
let min = ''
for(let i=0;i<characters.length;i++){
let element = characters[i];
if(element === element.toLowerCase() && element !== element.toUpperCase())
min+=element
}
showMinus(min)
}
useEffect(()=>{
getPassLength()
},[])
return(
<>
<div className='classHeader'>
<ShowPassword password={password} icon={<HiOutlineClipboardList/>} />
</div>
<div className='longBox'>
<p>Character Length</p>
<input type="range" min={1} max={16} step={1} ref={range} name="password" ></input>
{long}
</div>
<CapitalLetters
updatePassword={ShowPass}
showMinus={showMinus}
activeLetters={activeLetters}
longitud={long} />
</>
)
Hello everyone, I would like your help please: I am in a situation with the code, what I want to do is the following:
It is a password generator when I give it send
this generates a random password for me when I click the submit button, for this I have created an external component called showPassword that receives a prop called password So, so far so good because I manage to do that, my problem comes in the form file because I have some checkboxes, I want that when push lowercase it sends the password to the screen in only lowercase, that's where my problem is I don't know how to do it,
how do you think i should do it?
So on checkbox click use a state to see whether the ckeckbox is clicked on not. If yes there are js function to convert string to lowercase.
The toLowerCase() method converts a string to lower case letters.
Create a state that will control whether the checkbox is checked or not then inside the props you can create a ternary operator that will send a lowercase if checked or a normal password if not.
<ShowPassword password={isChecked ? password.toLowerCase() : password} icon={<HiOutlineClipboardList/>} />
Hope this works!

React useState not updating mapped content

I feel like im missing something that is staring me right in the face. I am trying to have content stored in an array of objects update when a checkbox is on or off. The console log is showing the object data is updating correctly so I assume my fault resides in not understanding useState fully?
const [statistics, setStatistics] = useState([
{
id: 1,
content: <div>Content1</div>,
state: true,
},
{
id: 2,
content: <div>Content2</div>,
state: true,
},
]);
In the component:
{statistics.map((item) => (item.state ? item.content : <></>))}
<input
type="checkbox"
onChange={(e) => {
let newArr = statistics;
e.target.checked
? (newArr[0].state = true)
: (newArr[0].state = false);
setStatistics(newArr);
console.log(statistics);
}}
/>
You are trying to change the state directly, instead you need to work with a copy of the state and make all changes to it.
Just replace in your code this string:
let newArr = statistics; // as link to base array
to
let newArr = [...statistics]; // as new copy of base array
and it will works.
React skips all state changes if they are made directly.
To create a new array as copy/clone of another array, in ES6, we can use the spread operator. You can not use = here, since it will only copy the reference to the original array and not create a new variable. Just read here for reference.
In your case, your newArray will refer to the old statistics and will not be detected as the new state. That is why no re-render takes place after you made changes to it.
So here, you can do this:
return (
<>
{statistics.map((item) => (item.state ? item.content : <></>))}
<input
type="checkbox"
onChange={(e) => {
setStatistics((prevStats) => {
const newStats = [...prevStats];
e.target.checked
? (newStats[0].state = true)
: (newStats[0].state = false);
return newStats;
});
}}
/>
</>
);

Writing javascript in JSX with expression

I am trying to understand the concept of writing expression in JSX but unable to understand that how is not javascript in curly braces an expression?
const Welcome()=>{
const isLoggedIn = true;
return(
<div>
{
if(isLoggedIn){
<p>Welcome!</p>
}else{
<p>Please Login</p>
}
}
</div>
);
}
Please guide me either when we assign a value isLoggedIn is true then validation happens, if value is true then it prints Welcome otherwise please log in.
Please tell me how is this a statement and not an expression.
If you want to use if then you have to use ternary operator because if in java scripts are statements, not expressions.
const Welcome = () => {
const isLoggedIn = true;
return (<div>{isLoggedIn ? <p>Welcome!</p> : <p>Please Login</p>}</div>);
}
if statements in JavaScript are, by definition, statements, and not expressions.
An expression can be considered as code that you can assign to a variable:
const myVar = 2 + 2;
const otherVar = someFuncCall();
Here, 2 + 2 and someFuncCall() are expressions because they can be assigned to a variable.
An if statement can't be assigned to a variable:
const invalidCode = if (someCondition) { "ABC"; } // This code won't run
You can use a ternary operator instead, which can be used to create expressions just like any other operators (e.g. + operator):
const Welcome = () => {
const isLoggedIn = true;
return(
<div>
{isLoggedIn ? (<p>Welcome!</p>) : (<p>Please Login</p>)}
</div>
);
}
This code works, because it's possible to assign this result to a variable:
const myJsx = isLoggedIn ? (<p>Welcome!</p>) : (<p>Please Login</p>)

Clarification needed on React's JSX syntax

I am learning to code in React and bit confused with JSX syntax.
I tried to understand but getting confused again and again.
It will be better if someone explains to me what exactly happening here with this code and what is the problem.
Here I am trying to iterate over form element array with below code:
const form = formElementArray.map(element =>{
<Input
key = {element.id}
elementType={element.config.elementType}
elementConfig={element.config.elementConfig}
value={element.config.value}
inValid = {!element.config.valid}
touched = {element.config.touched}
changed={(event)=>this.onChangeHandler(event,element.id)}
shouldValidate={element.config.validation}>
</Input>
})
Error: Expected an assignment or function call and instead saw an expression.
when using arrow function can emit the return keyword when you don't provide open/close brackets.
to fix remove { and } from your arrow function
const form = formElementArray.map(element =>
<Input
key = {element.id}
elementType={element.config.elementType}
elementConfig={element.config.elementConfig}
value={element.config.value}
inValid = {!element.config.valid}
touched = {element.config.touched}
changed={(event)=>this.onChangeHandler(event,element.id)}
shouldValidate={element.config.validation}>
</Input>
)
JSX expression:
{<div>some html tag with one root tags. wrapping brackets { and } </div>}
JSX means JavaScript XML. that says, you can write html in your JavaScript file.
Arrow function:
const randomFunc1 = (param) => {
var data = 'some data' + param;
return data;
}
OR
const randomFunc2 = param => {
var data = 'some data' + param;
return data;
}
OR
const randomFunc3 = param => 'some data' + param;
Above randomFunc1, randomFunc2, randomFunc3 doing same as one. randomFunc3 is the shortest syntax.
Your code is ok. but map function needs to return statement to create a new array. so just need a return keyword before <Input> tag

Leading Zeroes in React form

I'm an intermediate React developer. I'm building a form with React, Redux, and React Number Format. For the most part things are going well, but I'm a bit hung up on how to get rid of leading zeroes for my component. I think I understand the problem but I'm not sure where the right place to intervene is.
My app is deployed here. Here's my code defining my number field (from customInput.js)
<NumberFormat
value = {this.props.input.value || 0}
onFocus = {()=>{}}
onBlur = {this.handleChange.bind(this)}
onChange = {this.handleChange.bind(this)}
onInput = {this.handleChange.bind(this)}
thousandSeparator = {true}
prefix = {this.props.prefix}
suffix = {this.props.suffix}
decimalScale = {1}
isAllowed={(values) => {
const {floatValue} = values;
if (typeof floatValue==='undefined') {
return true;
}
if (this.props.maximum) {
return floatValue <= this.props.maximum;
} else {
return true;
}
}}
/>
It may be more helpful to look at my full code on GitHub.
This is my diagnosis of the problem. My input is taking its value from props, not from state. I found this easier when creating some of the field logic to avoid double renderings. When a field is changed, the change is dispatched to the Redux store. The field's state is not really used at all. I'm not sure if this is good practice, but it has worked well for me.
The problem is that when I dispatch a change adding a leading zero, Redux does not recognize it as a change. For example "005" and "5" are both seen as 5. Therefore, the component does not re-render. I've tried a lot of different fixes, but nothing resolves this issue.
Anyone have a recommendation?
OK, I found a fix. Adding to the isAllowed prop ended up being the correct point of intervention. Here's what I ended up with:
<NumberFormat
value = {this.props.input.value}
onFocus = {()=>{}}
onBlur = {this.handleChange.bind(this)}
onChange = {this.handleChange.bind(this)}
onInput = {this.handleChange.bind(this)}
thousandSeparator = {true}
prefix = {this.props.prefix}
suffix = {this.props.suffix}
decimalScale = {1}
isNumericString = {true}
isAllowed={(values) => {
const {value, floatValue} = values;
if (typeof floatValue==='undefined' || typeof value==='undefined') {
return true;
}
if (value.charAt(0)==='0') {
if (value.charAt(1) && value.charAt(1)!='.') {
return false
}
}
if (this.props.maximum) {
return floatValue <= this.props.maximum;
} else {
return true;
}
}}
/>
I think you may use like this:
value={parseInt(this.props.input.value, 10) || 0}
or
value={() => {return parseInt(this.props.input.value, 10)}}
Kind regards

Resources