Set state and then reading the state shows the previous value [duplicate] - javascript

This question already has answers here:
React setState not updating state
(11 answers)
Closed 3 years ago.
I have the following code that maintains the value when the textbox value is changed. However, whilst debugging the valueHasChangedEvent the variable x line shown below holds the previous value strangely. Is there something I'm doing wrong? The example shown is when I enter 'test123' into the textbox.
Thanks
onChange event
<Input onChange={this.valueHasChangedEvent}
type="text"
name="test"
id="test" />
Method
valueHasChangedEvent = (event) => {
var self = this;
const { name, value } = event.target;
self.setState({test: value}); // value = 'test123'
var x = self.state.test; // x = 'test12'
}

State needs some time to change, and since you are reading the state value before the state mutates, you get the previous value as output. So you need to write it in the callback to the setState function or read it in shouldComponentUpdate()
var x;
self.setState({test: value}, (x) => {
x = self.state.test
});

Related

Can you use a while loop in React? [duplicate]

This question already has answers here:
The useState set method is not reflecting a change immediately
(15 answers)
Closed 27 days ago.
Problem : I am trying to create an array of 4 things from a list but the while loop always produces an infinite loop.
const [options, setOptions] = useState([]);
const getThings = () => {
while(options.length < 4) {
let randomThing =
listOfThings[Math.floor(Math.random()*listOfThings.length)];
!options.includes(randomThing) && setOptions([...options, randomThing]);
}
};
I believe the problem is connected to another issue - when I call the function once, it is randomly called anywhere between 2 - 9 times even without the while loop attached. Still trying to figure out why it keeps randomly firing so much.
getThings();
setState does not instantly change any values. Create the entire array first, then set the state at the end of the loop.
const getThings = () => {
let newOptions = [...options];
while (newOptions.length < 4) {
let randomThing = listOfThings[Math.floor(Math.random()*listOfThings.length)];
if (!newOptions.includes(randomThing)) newOptions.push(randomThing);
}
setOptions(newOptions);
};
The error is caused because you are calling setOptions inside a loop, you could cache a new output in the function and then call the hook at the end
https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level

javaSript function parameters [duplicate]

This question already has answers here:
How to pass arguments to addEventListener listener function?
(36 answers)
addEventListener("click",...) firing immediately [duplicate]
(3 answers)
Closed last month.
I have an input field that I want to delete the value of onblur so ,I wrote a function to do so , it's not working for some reason .
HTML
<input class="add-class" type="text">
javaScript
let addClassInput = document.querySelector(".add-class");
let deleteOnblur = function (ele) {
ele.value = ""
};
addClassInput.addEventListener("blur", deleteOnblur(addClassInput));
It works when I do ...
let deleteOnblur = function () {
addClassInput.value = ""
};
addClassInput.addEventListener("blur", deleteOnblur);

Unable to change a variable value dynamically by passing it as a function parameter [duplicate]

This question already has answers here:
Pass variables by reference in JavaScript
(16 answers)
Closed 3 years ago.
In the following code, why am I not able to update a barcode value dynamically? I want to update the code value using updatecode(str, code) but still getting empty
var barcode;
var shapecode = "";
var typecode = "";
function updatecode(str, code) {
str = code;
}
function updatebarcode() {
barcode = shapecode +"-"+ typecode;
console.log(barcode);
}
updatecode(shapecode, 200);
updatecode(typecode , 200);
updatebarcode();
The 'str' variable is a functional-level variable. Modifying it wont effect the external variable. You should do sth like you do to modify barcode. You can do this:
let barcode;
let shapecode = '';
let typecode = '';
function updatecode(str, code) {
str == 'shapecode' ? (shapecode = code) : (typecode = code);
}
function updatebarcode() {
barcode = shapecode + '-' + typecode;
console.log(barcode);
}
updatecode('shapecode', 200);
updatecode('typecode', 200);
updatebarcode(); // logs 200-200;
You can't pass a value by reference like you want to do. This thread answers well your question: Pass Variables by Reference in Javascript
The problem you are running into here is the difference between pass by reference and pass by value.
When you call a javascript function with a primitive (such as a string), it doesn't pass the same variable into the function. Instead it makes a copy of the value of that variable, then passes in a new variable with that value. So when you modify str inside updatecode, it is modifying a variable local to that function, rather than the variable you passed into it.
I'm not 100% sure if you can pass a primitive by reference, but I know you can pass an object by reference, so maybe try this (it's a bit hacky but I'm not totally sure what you're trying to do, so trying to make it work within the context of the code you posted):
var barcode;
var codeObject = {
shape: '',
type: ''
};
function updatecode(object, key, code) {
object[key] = code;
}
function updatebarcode() {
barcode = codeObject.shape +"-"+ codeObject.type;
console.log(barcode);
}
updatecode(codeObject, 'shape', 200);
updatecode(codeObject, 'type' , 200);
updatebarcode();

simple javascript JS event handler not working correctly

Below is my code and the instructions that went with it. Currently the responseText for an incorrect answer displays on page load and I can't change it to the correct answer.
// Declare a string variable called question and set it equal to a True/False question of your choice.
var question = "KD has sold his legacy at OKC for a championship ring at GS.";
// Declare a boolean variable called answer and set it equal to true or false (the answer to the question you asked above.)
var answer = true;
// Create a function called loadQuestion() that sets the value of the questionText element equal to the question variable you declared above.
function loadQuestion(){
document.getElementById("questionText").innerHTML = question;
}
// Create a function called checkAnswer(userAnswer) that takes one incoming parameter.
function checkAnswer(userAnswer){
if(userAnswer===answer){
document.getElementById("responseText").innerHTML = "That is correct!";
document.getElementById("responseText").className = "correctAnswer";
}
else if(userAnswer!==answer){
document.getElementById("responseText").innerHTML = "I'm sorry, that is
not correct.";
document.getElementById("responseText").className = "incorrectAnswer";
}
}
// ---> If your answer variable matches the incoming userAnswer parameter, write a success message in the element called responseText.
// ---> If your answer variable does NOT match the userAnswer parameter, write a failure message in the element called responseText.
// Create TRADITIONAL DOM EVENT HANDLERS for the "onclick" events for the three buttons.
var start = document.getElementById("startButton");
var truth = document.getElementById("trueButton");
var falsify = document.getElementById("falseButton");
// The Start button should trigger the loadQuestion method
start.onclick = loadQuestion;
// The True button should trigger the checkAnswer method with a value of "true"
truth.onclick = checkAnswer("true");
// The False button should trigger the checkAnswer method with a value of "false"
falsify.onclick = checkAnswer("false");
if you are comparing as triple equality === make sure that type is the same on both sides
it should be
<...>.onclick = function() {
checkAnswer("true");
}
instead of
<...>.onclick = checkAnswer("true");

Assigning a value to an object children with a for loop doesn't work [duplicate]

This question already has answers here:
jQuery AJAX calls in for loop [duplicate]
(2 answers)
Closed 6 years ago.
http://codepen.io/noczesc/pen/ZWppJQ?
function codeToName(data) {
for (var i = 0; i < data.country.borders.length; i++) {
$.getJSON("https://restcountries.eu/rest/v1/alpha?codes=" + data.country.borders[i], function(json) {
data.country.borders[i] = json[0].name;
console.log(json[0].name);
});
}
};
I'm getting an array of country codes which are supposed to be changed to their full representations in English via the codeToName loop and an API, but it only appends a random name to the end of the array. To get a console.log of it, click on the <body>. It's located in JSONextract.country.borders. The country names grabbed via API are correct (logged in console also), but they don't get assigned to the variables inside my object. How can I solve this issue?
for does not work, you should use $.each
function codeToName(data) {
$.each(data.country.borders, function(index,item){
$.getJSON("https://restcountries.eu/rest/v1/alpha?codes=" + item, function(json) {
data.country.borders[index] = json[0].name;
console.log(json[0].name);
});
});
};

Categories