I'm trying to manipulate the DOM by inserting 2 values - reactjs

/////////index.ts///////
const Front =() =>{
const [inputs, setInputs] = useState({});
};
const addinputs = useCallback((event) => {
const name = event.target.name;
const value = event.target.value;
setInputs(values => (
{...values, [name]: value}))
},[inputs]);
return (
<>
<h1 id="header1">write you Thoughts</h1>
<label htmlFor='txtname'>Ente your name</label><br></br>
<input name="name" onChange={addinputs} value={inputs.name || ""} type="Text" id="txtname" ></input><br></br>
<label htmlFor="txtname">What are you thinking of</label><br></br>
<input name="thought" onChange={addinputs} value={inputs.thought || ""} id="txt1" type="Text"/><br></br>
<Thoughts addThought={addinputs}></Thoughts>
<hr/>
</>
)
/////////thoughts.ts///////
import {memo} from 'react'
const Thoughts = ({inputs ,addThought}) =>
{
console.log(inputs);
return(
<>
<h1>new thought</h1>
{inputs?.map((input,index) =>
{
return <p key={index}>{input}</p>
})}
<button onClick={addThought} type='button'>Add thought</button>
</>
);
};
export default memo(Thoughts);
but in console.log(inputs) I get undefined ,someone have a clue why?

inputs is a state inside the index.ts.You need to pass the inputs to Thoughts component
<Thoughts addThought={addinputs} inputs={inputs}></Thoughts>

Related

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>
);
}

How to split a simple HTML page into multiple React components and share states?

I am new to React Js. Could someone please explain how to translate this example to ReactJs? Specifically, if you have to organize the code into 3 components, how would you share the states between these component?
<label for="inputNumberOfCheckboxes">Enter number of checkboxes:</label> <input type="text" id ="inputNumberOfCheckboxes">
<ol id="listOfCheckboxes">
</ol>
<p id="printNumberOfSelectedCheckboxes">None</p>
<script type="text/javascript">
const inputNumberOfCheckboxes = document.getElementById('inputNumberOfCheckboxes');
const listOfCheckboxes = document.getElementById('listOfCheckboxes');
const printNumberOfSelectedCheckboxes = document.getElementById('printNumberOfSelectedCheckboxes');
inputNumberOfCheckboxes.addEventListener('change', () => {
const n = parseInt(inputNumberOfCheckboxes.value);
listOfCheckboxes.innerHTML = '';
for (let i = 0; i < n; i++) {
listOfCheckboxes.innerHTML += `
<li>
<input type="checkbox">
</li>`;
}
const refreshCount = () => {
const count = listOfCheckboxes.querySelectorAll('input:checked').length;
printNumberOfSelectedCheckboxes.innerHTML = `${count} checked`;
};
for (let checkbox of listOfCheckboxes.childNodes) {
checkbox.addEventListener('change', refreshCount);
}
});
</script>
In one component:
export default function App() {
const [inputValue, setInputValue] = React.useState("");
const [checkedItems, setCheckedItems] = React.useState([]);
const getRows = () => {
const length = inputValue > 0 ? inputValue : 0;
const arr = Array.from({ length }, (_, i) => i + 1);
return (
<ol>
{arr.map((item) => (
<li key={item}>
<input
onChange={() => {
const items = checkedItems.includes(item)
? checkedItems.filter((num) => num !== item)
: [...checkedItems, item];
setCheckedItems(items);
}}
type="checkbox"
checked={checkedItems.includes(item)}
/>
</li>
))}
</ol>
);
}
};
return (
<div className="App">
<label htmlFor="inputNumberOfCheckboxes">
Enter number of checkboxes:
</label>
<input
name="inputNumberOfCheckboxes"
type="number"
onChange={(e) => setInputValue(e.target.value)}
value={inputValue}
/>
<ol>{getRows()}</ol>
{inputValue > 0 ? null : <p>None</p>}
checked items: {checkedItems.length}
</div>
);
}
working example
Splitted:
Input.js
export default function Input({ name, value, onChange }) {
return (
<div>
<label htmlFor={name}>Enter number of checkboxes:</label>
<input
name={name}
type="number"
onChange={(e) => onChange(e.target.value)}
value={value}
/>
</div>
);
}
List.js
export default function List({ inputValue, checkedItems, setCheckedItems }) {
const length = inputValue > 0 ? inputValue : 0;
const arr = Array.from({ length }, (_, i) => i + 1);
return (
<ol>
{arr.map((item) => (
<li key={item}>
<input
onChange={() => {
const items = checkedItems.includes(item)
? checkedItems.filter((num) => num !== item)
: [...checkedItems, item];
setCheckedItems(items);
}}
type="checkbox"
checked={checkedItems.includes(item)}
/>
</li>
))}
</ol>
);
}
Summary.js
export default function Summary({ inputValue, checkedItems }) {
return (
<p>
{inputValue > 0 ? null : <p>None</p>}
checked items: {checkedItems.length}
</p>
);
}
App.js
export default function App() {
const [inputValue, setInputValue] = React.useState("");
const [checkedItems, setCheckedItems] = React.useState([]);
return (
<div className="App">
<Input onChange={setInputValue} value={inputValue} />
<List
name="inputNumberOfCheckboxes"
inputValue={inputValue}
checkedItems={checkedItems}
setCheckedItems={setCheckedItems}
/>
<Summary inputValue={inputValue} checkedItems={checkedItems} />
</div>
);
}
working example

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;

useState doesn't change the state in React

[Mycode] (https://codesandbox.io/s/romantic-kowalevski-fp00l?file=/src/App.js)
I'm practicing React by making todo-list app.
I want my input empty when i hit Enter. but it didn't work.
here is my whole code :
const Todo = ({ text }) => {
return (
<div>
<span>{text}</span>
</div>
);
};
const InputText = ({ addTodo }) => {
const [txt, setTxt] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
if (!txt) return;
addTodo(txt);
setTxt("");
};
return (
<form onSubmit={handleSubmit}>
<input type="text" onChange={(e) => setTxt(e.target.value)}></input>
</form>
);
};
function App() {
const [todos, setTodos] = useState([]);
const addTodo = (text) => {
const newTodos = [...todos, text];
setTodos(newTodos);
};
return (
<>
<div className="todo-list">
{todos.map((val, idx) => {
return <Todo key={val + idx} text={val} />;
})}
<InputText addTodo={addTodo} />
</div>
</>
);
}
line 17 on the link, setTxt(""); doesn't change state of txt.
how can i fix it?
That is not a "controlled" component since you are not using the value property on the input.
Try
<input type="text" onChange={e => setTxt(e.target.value)} value={txt} />
https://reactjs.org/docs/forms.html
You actually need to set the input value to your state.
Try something like
<Input type="text" onChange={(e) => setTxt(e.target.value)} value={txt}/>
I hope it helps.

Resources