How to pass current value of state variable to function in react? - reactjs

I have a state variable count which changes when I update my form input .
Also I want to pass the current value of count to another function all but I am unable to do so as it still gets the initial value of count and not the updated one.
import React, { useState } from "react";
import SingleColor from "./SingleColor";
import Values from "values.js";
function App() {
const [color, setColor] = useState("");
const [error, setError] = useState(false);
const [count, setCount] = useState(10); ////////Here
const [list, setList] = useState(new Values("#f15025").all(10));
const handleSubmit = (e) => {
e.preventDefault();
try {
console.log("Before: " + count);
let colors = new Values(color).all(count); /////////Here
console.log("After: " + count);
setList(colors);
} catch (error) {
setError(true);
console.log(error);
}
};
return (
<>
<section className="container">
<h3>color generator</h3>
<form onSubmit={handleSubmit}>
<input
type="text"
value={color}
placeholder="#f15025"
onChange={(e) => setColor(e.target.value)}
className={`${error ? "error" : null} `}
/>
<input
type="number"
value={count}
onChange={(e) => {
setCount(e.target.value); /////////Updating
}}
style={{ marginLeft: "5px" }}
/>
<button className="btn" type="submit">
submit
</button>
</form>
</section>
<section className="colors">
{list.map((color, index) => {
// console.log(color);
return (
<SingleColor
key={index}
{...color}
index={index}
hexColor={color.hex}
/>
);
})}
</section>
</>
);
}
export default App;
How can I pass the current value of count to the function all ?

Related

How Do I give dynamic colors to the each list here

import React, { useState, useEffect } from "react";
import "./style.css";
const getLocalItem = () => {
let list = localStorage.getItem("lists");
console.log(list);
if (list) {
return JSON.parse(list);
} else {
return [];
}
};
function App() {
const [text, setText] = useState("");
const [task, setTask] = useState(getLocalItem());
const changeText = (e) => {
setText(e.target.value);
};
const submitHandler = (e) => {
console.log("submited");
e.preventDefault();
setTask([...task, text]);
setText("");
};
const removeTask = (a) => {
const finalData = task.filter((curEle, index) => {
return index !== a;
});
setTask(finalData);
};
useEffect(() => {
localStorage.setItem("lists", JSON.stringify(task));
}, [task]);
return (
<>
<form onSubmit={submitHandler} className='form'>
<div className="action" >
<div >
<input
className="input"
type="text"
value={text}
onChange={changeText}
placeholder='add task...'
/>
</div>
<button type="submit" className="button" >
Add todo
</button>
</div>
<div className="listsData">
{task.map((value, index) => {
return (
<>
<div key={index}>
{value}
</div>
</>
);
})}
</div>
</form>
</>
);
}
export default App;
On adding each item I want a different color for each list. Currently, I am fetching list data from localstorage while fetching also it should remain same. which is working but the dynamic colors is what I need for each list. Any ideas or dynamic logics??
Let me know if u need more details regarding my code if u doont understand something

How to update the value of state variable passed to function in react?

I was trying to add a state variable which would update on changing form input .I have a function handleSubmit which would be called on submitting the form. I wanted to pass the updated value of my state variable to another function all inside my handleSubmit function but the value passed to the function never gets updated even after many times submitting the form.
It's something like this...
const handleSubmit = (e) => {
e.preventDefault();
try {
let colors = new Values(color).all(count);
setList(colors);
} catch (error) {
setError(true);
console.log(error);
}
};
I also have a similar input which updates my other state variable color .What is happening is on submitting the form, new Values() is giving me an object with updated value of color but old value of count
Link to original project: https://github.com/john-smilga/react-projects/blob/master/09-color-generator/final/src/App.js
Link: https://react-projects-9-color-generator.netlify.app/
What I have tried to do:
import SingleColor from "./SingleColor";
import Values from "values.js";
function App() {
const [color, setColor] = useState("");
const [error, setError] = useState(false);
const [count, setCount] = useState(10); ////////Here
const [list, setList] = useState(new Values("#f15025").all(10));
const handleSubmit = (e) => {
e.preventDefault();
try {
console.log("Before: " + count);
let colors = new Values(color).all(count); /////////Here
console.log("After: " + count);
setList(colors);
} catch (error) {
setError(true);
console.log(error);
}
};
return (
<>
<section className="container">
<h3>color generator</h3>
<form onSubmit={handleSubmit}>
<input
type="text"
value={color}
placeholder="#f15025"
onChange={(e) => setColor(e.target.value)}
className={`${error ? "error" : null} `}
/>
<input
type="number"
value={count}
onChange={(e) => {
setCount(e.target.value); /////////Updating
}}
style={{ marginLeft: "5px" }}
/>
<button className="btn" type="submit">
submit
</button>
</form>
</section>
<section className="colors">
{list.map((color, index) => {
// console.log(color);
return (
<SingleColor
key={index}
{...color}
index={index}
hexColor={color.hex}
/>
);
})}
</section>
</>
);
}
Any other way of dynamically passing the value to the all function ?

How to add items to array in react

Code:
export default function App() {
const [name,setName] = useState("");
var myArray = [];
const handleAdd = () => {
myArray = [...myArray,name]
setName("")
}
return (
<div className="App">
<input placeholder="type a name" onChange={(e) => setName(e.target.value)}/>
<button onClick={handleAdd}>add</button>
<button onClick={() => console.log(myArray)}>test</button>
{myArray.map((n) => {
return <h2>{n}</h2>
})}
</div>
);
}
OnClick it isn't adding the name to the array.
this is how you "push" to an array with useState
const [array, setArray] = useState([])
setArray(previous => [...previuous, newItem])
You should use a state for your array and set that state to see the changes reflected:
export default function App() {
const [name, setName] = useState('');
const [myArray, setMyArray] = useState([]);
const handleAdd = () => {
setMyArray([...myArray, name]);
setName('');
};
return (
<div className="App">
<input
placeholder="type a name"
onChange={(e) => setName(e.target.value)}
/>
<button onClick={handleAdd}>add</button>
<button onClick={() => console.log(myArray)}>test</button>
{myArray.map((n) => {
return <h2>{n}</h2>;
})}
</div>
);
}
We can also set the state of myArr to be an empty array initially, making it easier to manipulate the subsequent state of that array. The onClick event handler does not fire the handleAdd function, for some reason, it only resets the form and does not provide any state. To submit the form and materialize the state, we can also use the onSubmit event handler instead of onClick. In the same way, we can use the name state as a value/prop for the name input, which will be used by the onChange handler.
import React, { useState } from 'react'
const App = () => {
const [name, setName] = useState('')
const [myArr, setMyArr] = useState([])
const submit = (event) => {
event.preventDefault()
setMyArr(myArr.concat(name))
setName('')
}
//console.log(myArr)
return (
<div className="App">
<form onSubmit={submit}>
<div>
<label htmlFor="name">Name</label>
<input
placeholder="type a name"
type="text"
value={name}
onChange={({ target }) => setName(target.value)}
/>
</div>
<div>
<button type="submit">Add</button>
</div>
</form>
<div>
{myArr.map((arr, index) => (
<div key={index}>
<p>{arr}</p>
</div>
))}
</div>
</div>
)
}
export default App
I have a proclivity of inserting items on an array using concat.
import React, { useState } from 'react'
// ...
const App = () => {
// ...
const [myArr, setMyArr] = useState([])
// somewhere on your event handler e.g. Submit handler
setMyArr(myArr.concat(name))
// ...
}

Dynamic arrayfield delete operation in Reactjs?

As a Begineer in a react,i have just implementing a dynamic array field for learning but got a problem in delete operation of removing inputs fields from the row field with passing its id in deletefunction.How to overcome this problem?
Code
import React, { useState} from "react";
import "./styles.css";
const initialValues = [
{number: "",options: ""}
];
const Newrow = (props) => {
const [number, setNumber] = useState("");
const [options, setoption] = useState([]);
const addRow = () => {
let _row = {
number: "",
options: ""
};
props.setData(_row);
};
const delrow = (i) => {
data.splice(i,2)
setData({})
}
return <div>
<input
type="number"
value={number}
onChange={(e) => {
setNumber(e.target.value);
}}
/>
<input type="text"
className="input"
value={options}
onChange={e=>{setoption(e.target.value)}}
/>
<button
type="submit"
onClick={delrow}
className="btn btn-danger">remove</button>
</div>
};
export default function App(props) {
const [data, setData] = useState([]);
const addRow = (row) => {
setData([...data, row]);
};
return (
<div className="App">
{[...data, ...initialValues].map((row, idx) => {
return <Newrow setData={addRow} data={row} key={idx} delrow{idx} />;
})}
<button
type="submit"
onClick={() =>
addRow({number: "",options: "" })}
className="btn btn-success">Add</button>
</div>
);
}

Input not re-rendering onChange with hooks

When typing and logging the input e.target.value, I get the default value + the last key stroke, but nothing re-renders. I guess that React doesn't recognize that the state changed, but I'm having a problem finding out the correct way to do this.
This is the code in question:
const [text, setText] = useState(task.text);
console.log(text);
const handleInputChange = (e) => {
setText(e.target.value);
};
const taskInput = (
<form>
<input type='text' value={text} onChange={handleInputChange} />
</form>
);
And the full file:
import React, { useContext, useState } from "react";
import { TaskContext } from "../context/TaskState";
const Task = ({ task }) => {
const { deleteTask } = useContext(TaskContext);
const { changeStatus } = useContext(TaskContext);
const taskText = (
<div
className='task-text'
onClick={() => changeStatus({ ...task, done: !task.done })}
style={task.done ? { textDecoration: "line-through" } : null}
>
{task.text}
</div>
);
const [text, setText] = useState(task.text);
console.log(text);
const handleInputChange = (e) => {
setText(e.target.value);
};
const taskInput = (
<form>
<input type='text' value={text} onChange={handleInputChange} />
</form>
);
const [option, setOption] = useState(taskText);
return (
<div className='task-container'>
<button className='task-edit' onClick={() => setOption(taskInput)}>
edit
</button>
<button className='task-delete' onClick={() => deleteTask(task.id)}>
x
</button>
{option}
</div>
);
};
export default Task;
I'am using global state for the rest of the app and reducers.
I think, onChange in your input might cause this error. Try replacing this:
onChange={handleInputChange}
with this:
onChange={(e) => handleInputChange(e)}
e object might be not passed to your method.
Please try wrapping your taskInput value in useMemo with dependency text as when you store JSX as variable during re-render they are refering to the previous value as they don't know the variable they used have value changed.
import React, { useMemo, useContext, useState } from "react";
const taskInput = useMemo(() => (
<form>
<input type='text' value={text} onChange={handleInputChange} />
</form>
), [text]);
The problem was the way I passed option inside the jsx.
I made the option state a boolean, converted taskText and taskInput to functions and passed option conditionally inside the jsx.
import React, { useContext, useState } from "react";
import { TaskContext } from "../context/TaskState";
const Task = ({ task }) => {
const { deleteTask } = useContext(TaskContext);
const { changeStatus } = useContext(TaskContext);
const taskText = () => {
return (
<div
className='task-text'
onClick={() => changeStatus({ ...task, done: !task.done })}
style={task.done ? { textDecoration: "line-through" } : null}
>
{task.text}
</div>
);
};
const [text, setText] = useState(task.text);
console.log(text);
const handleInputChange = (e) => {
setText(e.target.value);
};
const taskInput = () => {
return (
<form>
<input type='text' value={text} onChange={handleInputChange} />
</form>
);
};
const [option, setOption] = useState(true);
return (
<div className='task-container'>
<button className='task-edit' onClick={() => setOption(!option)}>
edit
</button>
<button className='task-delete' onClick={() => deleteTask(task.id)}>
x
</button>
{option ? taskText() : taskInput()}
</div>
);
};
export default Task;

Resources